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
总结:不要再折磨我了

浙公网安备 33010602011771号