PAT-Battle Over Cities - Hard Version (35 分)-最小生成树
Posted justdoa
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PAT-Battle Over Cities - Hard Version (35 分)-最小生成树相关的知识,希望对你有一定的参考价值。
这个题的题意是假设某个城市被占领后,要使剩下的城市保持联通可能会花钱修路,求最小花费里花费最多的那个被占领的城市。
这个题凭感觉就是最小生成树,最小生成树满足权值最小(最小花费),所以依次去掉某个城市的所有与其相接的路径,把剩下的路加入最小生成树,求最大值即可。
有一个地方写的时候没注意到,就是去掉某个城市后可能导致连通块的数量的增多,这种情况下算这个城市的花费无限大就可以了(自己真菜QAQ)。
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <queue> #include <vector> #include <cmath> using namespace std; const int INF = 0x3f3f3f3f; int n,m,max1; int f[505]; vector<int> ans; struct P int u,v,c,s; bool operator<(const P &a)const if(s != a.s) return s > a.s;//优先选择还能用的路,这种路径不增加花费 else return c<a.c;//其实是处理需要修理的路径,先修花费少的 p[250005]; int Find(int x) if(x==f[x]) return x; else return f[x]=Find(f[x]); int main() scanf("%d%d",&n,&m); max1=0; for(int i=1;i<=m;i++) scanf("%d%d%d%d",&p[i].u,&p[i].v,&p[i].c,&p[i].s); sort(p+1,p+1+m); for(int i=1;i<=n;i++) int num=0,cnt=0; for(int i=1;i<=n;i++) f[i]=i; for(int j=1;j<=m;j++) if(num==n-2) break; int u=p[j].u; int v=p[j].v; if(u==i || v==i) continue ;//去掉某个城市 u=Find(u); v=Find(v); if(u!=v) f[u]=v; num++; if(p[j].s==0) cnt+=p[j].c; if(num!=n-2)//先判断删除某个城市后是否连通 if(max1!=INF) max1=INF; ans.clear(); ans.push_back(i); else if(cnt>max1) max1=cnt; ans.clear(); ans.push_back(i); else if(cnt==max1 && max1!=0) ans.push_back(i); if(ans.size()==0) printf("0\n"); else sort(ans.begin(),ans.end()); printf("%d",ans[0]); for(int i=1;i<ans.size();i++) printf(" %d",ans[i]); return 0;
以上是关于PAT-Battle Over Cities - Hard Version (35 分)-最小生成树的主要内容,如果未能解决你的问题,请参考以下文章