2 4 5 0 1 10 0 2 20 2 3 40 1 3 10 1 2 70 1 1 4 1 60 2 2 3 3 3 0 1 20 2 1 40 2 0 70 2 3 0 3 10 1 4 90 2 4 100 0
70 160
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int INF =1e8;
int mp[205][205];
int des[205];
int visi[205];
int low[205]; //更新最小值
int n;
int prim()
{
int i,j;
memset(visi,0,sizeof(visi));
for(i=0;i<=200;i++)
low[i]=INF;
int ans=0,pos=-1;
for(i=0;i<n;i++)
{
if(!des[i])
{
pos=i;
break;
}
}
if(pos==-1) return 0;
for(i=0;i<=200;i++)
low[i]=mp[pos][i];
visi[pos]=1;
int mi;
for(i=0;i<n;i++)
{
mi=INF;
int flag=0;
for(j=0;j<n;j++)
{
if(des[j]) continue;
if(!visi[j])
{
flag=1;
if(low[j]<mi)
{
mi=low[j];
pos=j;
}
}
}
if(mi==INF&&flag)
return -1;
if(!flag) return ans;
ans+=mi;
visi[pos]=1;
for(j=0;j<n;j++)
if(!visi[j])
low[j]=min(low[j],mp[pos][j]);
}
return ans;
}
int main()
{
int tes,i,j,res;
scanf("%d",&tes);
while(tes--)
{
int n1,m,u,v,val;
scanf("%d%d",&n1,&m);
for(i=0;i<=200;i++)
for(j=0;j<=200;j++)
mp[i][j]=INF;
memset(des,0,sizeof(des));
for(i=0;i<m;i++)
{
scanf("%d%d%d",&u,&v,&val);
if(mp[u][v]>val) //这个地方,边可能会多次给出,坑。。
{
mp[u][v]=val;
mp[v][u]=val;
}
}
int n2;
scanf("%d%d",&n2,&m);
for(i=0;i<m;i++)
{
scanf("%d%d%d",&u,&v,&val);
if(mp[u][v]>val)
{
mp[u][v]=val;
mp[v][u]=val;
}
}
n=n1+n2;
int t,x;
scanf("%d",&t);
for(i=0;i<t;i++)
{
scanf("%d",&x);
des[x]=1;
}
res=prim();
if(res==-1) puts("what a pity!");
else printf("%d\n",res);
}
return 0;
}
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int INF =1e6;
const int maxn=205;
int n,m,t; //总点数,总边数,desert的边数
int des[maxn]; //为1代表城市荒废
int fa[maxn];
struct Edge
{
int from;
int to;
int val;
}edge[maxn*maxn];
int cmp(Edge p1,Edge p2)
{
//if(des[p1.from]||des[p1.to]) return 0;
//if(des[p2.from]||des[p2.to]) return 1;
return p1.val<p2.val;
}
void init()
{
for(int i=0;i<=200;i++)
fa[i]=i;
}
int find1(int x)
{
if(fa[x]!=x) fa[x]=find1(fa[x]);
return fa[x];
}
void merge1(int p1,int p2)
{
p1=find1(p1);
p2=find1(p2);
fa[p1]=p2;
}
int Kruskal()
{
sort(edge,edge+m,cmp);
int ans=0,ste=0;
for(int i=0;i<m&&ste<n-t-1;i++)
{
int u=edge[i].from,v=edge[i].to,val=edge[i].val;
if(des[u]||des[v]) continue;
if(find1(u)!=find1(v))
{
ste++;
ans+=val;
merge1(u,v);
}
}
if(ste==n-t-1) return ans;
return -1;
}
int main()
{
int tes,i,j,res;
scanf("%d",&tes);
while(tes--)
{
int n1,m1,u,v,val,n2,m2;
scanf("%d%d",&n1,&m1);
memset(des,0,sizeof(des));
for(i=0;i<m1;i++)
{
scanf("%d%d%d",&u,&v,&val);
edge[i].from=u;
edge[i].to=v;
edge[i].val=val;
}
scanf("%d%d",&n2,&m2);
n=n1+n2;
m=m1+m2;
for(i=m1;i<m;i++)
{
scanf("%d%d%d",&u,&v,&val);
edge[i].from=u;
edge[i].to=v;
edge[i].val=val;
}
int x;
scanf("%d",&t);
for(i=0;i<t;i++)
{
scanf("%d",&x);
des[x]=1;
}
init();
res=Kruskal();
//cout<<n<<" :n"<<endl;
if(res==-1) puts("what a pity!");
else printf("%d\n",res);
}
return 0;
}
HDU 3080 The plan of city rebuild(prim和kruskal)
原文地址:http://blog.csdn.net/coraline_m/article/details/24676917