题目链接 http://acm.csu.edu.cn/OnlineJudge/problem.php?cid=2027&pid=5
题意就是让首都和其他城市连接起来,在花费不超过K的情况下使得人数最大。看了别人的才懂的= =代码如下:
//prim算法求最小生成树
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
#define maxn 1<<16
#define inf 0x7fffffff
int n,m,k;
int num[20];
int Map[20][20];
bool mark[20];
bool exits[20];
int d[20];
int p;
void work(int n)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
Map[i][j]=(i!=j?maxn:0);
}
}
}
int prim()
{
int sum=0;
memset(mark,false,sizeof(mark));
for(int i=1;i<=n;i++)
{
d[i]=Map[1][i];
}
mark[1]=true;
for(int i=2;i<=n;i++)
{
int minn=maxn;
int mini;
for(int j=1;j<=n;j++)
{
if(!mark[j]&&exits[j]&&d[j]<minn)
{
minn=d[j];
mini=j;
}
}
if(minn==maxn)
break;
sum+=minn;
mark[mini]=true;
for(int k=1;k<=n;k++)
{
if(exits[k]&&!mark[k]&&Map[mini][k]<d[k])
{
d[k]=Map[mini][k];
}
}
}
int ans1=0,ans2=0;
for(int i=1;i<=n;i++)
{
ans1+=exits[i];
}
for(int i=1;i<=n;i++)
{
ans2+=mark[i];
}
if(ans1==ans2)
return sum;
return maxn;
}
void dfs(int cur)
{
if(cur>n)
{
int pr=prim();
int tmp=0;
if(pr<=k)
{
for(int i=1;i<=n;i++)
{
if(exits[i])
{
tmp+=num[i];
}
}
if(tmp>p)
p=tmp;
}
return ;
}
for(int i=0;i<2;i++)
{
exits[cur]=i==1?true:false;
dfs(cur+1);
}
}
int main (void)
{
int t;
cin>>t;
while(t--)
{
scanf("%d %d %d",&n,&m,&k);
for(int i=1;i<=n;i++)
{
scanf("%d",&num[i]);
}
work(n);
for(int i=0;i<m;i++)
{
int u,v,c;
scanf("%d %d %d",&u,&v,&c);
if(Map[u][v]>c)
{
Map[u][v]=Map[v][u]=c;
}
}
p=num[1];
exits[1]=true;
dfs(2);
printf("%d\n",p);
}
return 0;
}