题目:http://acm.hdu.edu.cn/showproblem.php?pid=1879
题意:有n个城镇,给出 n*(n-1)/2 行关系,每行有4个数a,b,c,d。其中a,b表示城镇,c表示建路的金钱数,若d=0表示未建,d=1,表示已建。求把各个城镇全部连通需要多少钱。
想法:最小生成树,把已经建好的城镇之间的标记为0。感觉有一个很坑的地方就是只有把 cin>>a>>b>>c>>d>>c改成scanf("%d%d%d%d",&a,&b,&c,&d); 。才AC。否则会一直TLE。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int INF=1<<20;
bool vis[110];
int link[110][110],dis[110];
int n,ans;
void prim(){
for(int i=1;i<=n;i++)
dis[i]=link[1][i];
dis[1]=0;
for(int i=1;i<=n;i++){
int minn=INF,pos;
for(int j=1;j<=n;j++){
if(!vis[j]&&minn>dis[j]){
minn=dis[j];
pos=j;
}
}
ans+=minn;
vis[pos]=true;
for(int k=1;k<=n;k++){
if(!vis[k]&&dis[k]>link[pos][k])
dis[k]=link[pos][k];
}
}
}
int main(){
//freopen("123.txt","r",stdin);
while(~scanf("%d",&n)&&n!=0){
int a,b,c,d;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
link[i][j]=link[j][i]=INF;
}
}
for(int i=0;i<n*(n-1)/2;i++){
scanf("%d%d%d%d",&a,&b,&c,&d);
if(d==0){
if(link[a][b]>c)
link[a][b]=link[b][a]=c;
}
else
link[a][b]=link[b][a]=0;
}
memset(vis,false,sizeof(vis));
ans=0;
prim();
cout<<ans<<endl;
}
return 0;
}