您的位置:首页 > 其它

CSU 1116 Kingdoms

2013-11-18 11:48 465 查看
  原题链接:http://122.207.68.93/OnlineJudge/problem.php?id=1116

  由于n比较小,直接枚举,然后对于每一个状态用最小生成树算法验证即可,感觉是水过去的,复杂度O(2n*n*m)。(有状压DP做法?)

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 20

struct Node
{
int u, v, w;
}e[105];

int n, m, k, p
, ans, f
;

bool cmp(Node a, Node b)
{
return a.w < b.w;
}

int find(int x)
{
return f[x] == x ? x : (f[x] = find(f[x]));
}

bool ok(int cur)
{
int tot = 0;
for(int i = 0; i < n; i++) f[i] = i;
for(int i = 0; i < m; i++)
{
if(((cur>>e[i].u)&1) && ((cur>>e[i].v)&1))
{
int x = find(e[i].u);
int y = find(e[i].v);
if(x != y)
{
if(x > y)
f[x] = y;
else
f[y] = x;
tot += e[i].w;
}
}
}
for(int i = 0; i < n; i++) // 所有要验证的点都必须和capital在同一个连通分量里面
if((cur>>i)&1 && find(i) != 0) return false;
return tot <= k;
}

int main()
{
int t;
scanf("%d", &t);
while(t--)
{
scanf("%d%d%d", &n, &m, &k);
for(int i = 0; i < n; i++)
scanf("%d", &p[i]);
Node tmp;
for(int i = 0; i < m; i++)
{
scanf("%d%d%d", &tmp.u, &tmp.v, &tmp.w);
tmp.u--; tmp.v--;
e[i] = tmp;
}
sort(e, e+m, cmp);
ans = -1;
for(int i = 1; i < (1 << n); i++)
{
if(ok(i))
{
int tot = 0;
for(int j = 0; j < n; j++)
{
if((i >> j) & 1)
tot += p[j];
}
ans = max(ans, tot);
}
}
printf("%d\n", ans);
}
return 0;
}


View Code

  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: