acm专题七

一、第一题
代码:

#include <bits/stdc++.h>
using namespace std;
int main() 
{
	int f[210][210],n,i,m,j,k;
	while(cin>>n)
	{
		if(!n) return 0;
		memset(f,0x3f,sizeof f);
		for(i=1;i<=n;i++) f[i][i]=0;
		for(i=1;i<=n;i++)
		{
			cin>>m;
			for(j=1;j<=m;j++)
			{
				int a,b;cin>>a>>b;
				f[i][a]=b;
			}
		}
		for(k=1;k<=n;k++)
		for(i=1;i<=n;i++)
		for(j=1;j<=n;j++)
		f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
		int ans=0x3f3f3f3f,pos=0;
		for(i=1;i<=n;i++)
		{
			int flag=0,now=0;
			for(j=1;j<=n;j++)
			{
				if(f[i][j]==0x3f3f3f3f) flag=1;
				now=max(f[i][j],now);
			}
			if(now<ans&&!flag) ans=now,pos=i;
		}
		cout<<pos<<' '<<ans<<endl;
	}
    return 0;
}

思路:套用floyd算法计算任意两点最短距离,然后遍历所有起始点
二、第二题
代码:

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
vector<int> g[N];
int n,dep[N],i,d1[N],d2[N],ans;
void dp(int x,int f)
{
	d1[x]=d2[x]=0;
	for(auto y:g[x])
	{
		if(y==f) continue;
		dp(y,x);
		int dis1=d1[y]+1;
		if(dis1>d1[x]) d2[x]=d1[x],d1[x]=dis1;
		else if(dis1>d2[x]) d2[x]=dis1;
	}
	ans=max(ans,d1[x]+d2[x]);
}
int main() 
{
	cin>>n;
	for(i=0;i<n-1;i++) 
	{
		int a,b;cin>>a>>b;
		g[a].push_back(b),g[b].push_back(a);
	}
	dp(1,0);
	cout<<ans;
    return 0;
}

思路:dp法求直径,d1x的最长链,d2x的次长链
三、第三题
代码:

#include <iostream>
#include <vector>
#include <climits>
#include <algorithm>
using namespace std;
// 定义边的结构体
struct Edge {
    int to;
    int cost;
    Edge(int t, int c) : to(t), cost(c) {}
};
// 优化的 Dijkstra 算法
vector<int> dijkstra(const vector<vector<Edge>>& graph, int start) {
    int n = graph.size();
    vector<int> dist(n, INT_MAX);
    dist[start] = 0;
    vector<bool> visited(n, false);
    for (int i = 0; i < n; ++i) {
        int u = -1;
        for (int j = 1; j < n; ++j) {
            if (!visited[j] && (u == -1 || dist[j] < dist[u])) {
                u = j;
            }
        }
        if (u == -1) break;
        visited[u] = true;
        for (const Edge& edge : graph[u]) {
            int v = edge.to;
            int cost = edge.cost;
            if (dist[u] + cost < dist[v]) {
                dist[v] = dist[u] + cost;
            }
        }
    }
    return dist;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int N;
    cin >> N;
    while (N--) {
        int P, Q;
        cin >> P >> Q;
        // 正向图和反向图
        vector<vector<Edge>> graph(P + 1);
        vector<vector<Edge>> reverseGraph(P + 1);
        // 读取公交线路信息
        for (int i = 0; i < Q; ++i) {
            int u, v, cost;
            cin >> u >> v >> cost;
            graph[u].emplace_back(v, cost);
            reverseGraph[v].emplace_back(u, cost);
        }
        // 计算从 CCS 到各个站点的最短路径
        vector<int> distTo = dijkstra(graph, 1);
        // 计算从各个站点到 CCS 的最短路径
        vector<int> distFrom = dijkstra(reverseGraph, 1);
        // 计算总费用
        int totalCost = 0;
        for (int i = 1; i <= P; ++i) {
            totalCost += distTo[i] + distFrom[i];
        }
        // 输出结果
        cout << totalCost << endl;
    }
    return 0;
}

四、第四题
代码:

#include <bits/stdc++.h>
using namespace std;
const int N=1510;
int f[N][2],a[N],n;
vector<int> g[N];
void dp(int x,int fa)
{
	f[x][0]=0,f[x][1]=1;
	for(auto y:g[x])
	{
		if(y==fa) continue;
		dp(y,x);
		f[x][0]+=f[y][1],f[x][1]+=min(f[y][0],f[y][1]);
	}
}
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		int x,cnt;cin>>x>>cnt;
		for(int j=1;j<=cnt;j++)
		{
			int y;cin>>y;
			g[x].push_back(y),g[y].push_back(x);
		}
	}
	dp(0,-1);
	cout<<min(f[0][0],f[0][1]);
	return 0;
}

思路:树形dp

总结:不要再折磨我了

posted @ 2025-02-19 19:20  astronomyy  阅读(13)  评论(0)    收藏  举报