uva 12507 Kingdoms(dfs+最小生成树)
2017-06-09 20:36
344 查看
题意:
n(4-16)个点,每个点有权值,m条带权值的边,问在边权最多花费k的情况下,能让1这个点连通的点的权值加和最大为多少。
解题思路:
做题要看数据范围,n个点直接dfs枚举是否取2到n种的每个点,1肯定要取,然后用最小生成树把枚举出来的点连接,看是否能建成生成树,然后再看生成树的权值是否小于等于k,满足的情况算一下点权和,更新一下答案,就做完了。
代码:
#include <bits/stdc++.h>
using namespace std;
int p[105];
int a[105][105];
struct node
{
int x, y;
int c, is;
}edg[105];
int book[105];
int t, n, m, k, i, j, cnt;
int f[105];
int getf(int x)
{
if(f[x]==x)return x;
else return f[x]=getf(f[x]);
}
bool merg(int x, int y)
{
x=getf(x), y=getf(y);
if(x==y)
{
return false;
}
else
{
f[x]=y;
return true;
}
}
bool cmp(node a, node b)
{
return a.c<b.c;
}
int ans;
bool judge()
{
int x, y, c, sum=0;
// printf("cnt%d\n", cnt);
for(i=1; i<=n; i++)f[i]=i;
for(i=1, j=0; i<=m; i++)
{
x=edg[i].x, y=edg[i].y, c=edg[i].c;
/*
if(cnt==3)
{
printf("c%d %d %d\n", c, cnt ,j);
}
*/
if(book[x] && book[y] && merg(x,y))
{
sum+=c;
j++;
}
if(j>=cnt-1)break;
}
return sum<=k && j>=(cnt-1);
}
void dfs(int x)
{
if(x>n)
{
if(judge()==0)
{
return;
}
int sum=0;
for(i=1; i<=n; i++)
{
if(book[i])
{
// printf("%d ", i);
sum+=p[i];
}
}
// printf("%d\n", sum);
ans=max(sum, ans);
return;
}
cnt++;
book[x]=1;
dfs(x+1);
cnt--;
book[x]=0;
dfs(x+1);
return;
}
int main()
{
cin>>t;
while(t--)
{
// memset(a, 0, sizeof a);
memset(book, 0, sizeof book);
ans=0;
scanf("%d%d%d", &n, &m, &k);
for(i=1; i<=n; i++)scanf("%d", &p[i]);
int x, y, c;
for(i=1; i<=m; i++)
{
scanf("%d%d%d", &edg[i].x, &edg[i].y, &edg[i].c);
}
sort(edg+1, edg+m+1, cmp);
book[1]=1;
cnt=1;
dfs(2);
printf("%d\n", ans);
}
}
n(4-16)个点,每个点有权值,m条带权值的边,问在边权最多花费k的情况下,能让1这个点连通的点的权值加和最大为多少。
解题思路:
做题要看数据范围,n个点直接dfs枚举是否取2到n种的每个点,1肯定要取,然后用最小生成树把枚举出来的点连接,看是否能建成生成树,然后再看生成树的权值是否小于等于k,满足的情况算一下点权和,更新一下答案,就做完了。
代码:
#include <bits/stdc++.h>
using namespace std;
int p[105];
int a[105][105];
struct node
{
int x, y;
int c, is;
}edg[105];
int book[105];
int t, n, m, k, i, j, cnt;
int f[105];
int getf(int x)
{
if(f[x]==x)return x;
else return f[x]=getf(f[x]);
}
bool merg(int x, int y)
{
x=getf(x), y=getf(y);
if(x==y)
{
return false;
}
else
{
f[x]=y;
return true;
}
}
bool cmp(node a, node b)
{
return a.c<b.c;
}
int ans;
bool judge()
{
int x, y, c, sum=0;
// printf("cnt%d\n", cnt);
for(i=1; i<=n; i++)f[i]=i;
for(i=1, j=0; i<=m; i++)
{
x=edg[i].x, y=edg[i].y, c=edg[i].c;
/*
if(cnt==3)
{
printf("c%d %d %d\n", c, cnt ,j);
}
*/
if(book[x] && book[y] && merg(x,y))
{
sum+=c;
j++;
}
if(j>=cnt-1)break;
}
return sum<=k && j>=(cnt-1);
}
void dfs(int x)
{
if(x>n)
{
if(judge()==0)
{
return;
}
int sum=0;
for(i=1; i<=n; i++)
{
if(book[i])
{
// printf("%d ", i);
sum+=p[i];
}
}
// printf("%d\n", sum);
ans=max(sum, ans);
return;
}
cnt++;
book[x]=1;
dfs(x+1);
cnt--;
book[x]=0;
dfs(x+1);
return;
}
int main()
{
cin>>t;
while(t--)
{
// memset(a, 0, sizeof a);
memset(book, 0, sizeof book);
ans=0;
scanf("%d%d%d", &n, &m, &k);
for(i=1; i<=n; i++)scanf("%d", &p[i]);
int x, y, c;
for(i=1; i<=m; i++)
{
scanf("%d%d%d", &edg[i].x, &edg[i].y, &edg[i].c);
}
sort(edg+1, edg+m+1, cmp);
book[1]=1;
cnt=1;
dfs(2);
printf("%d\n", ans);
}
}
相关文章推荐
- Kingdoms UVA - 12507 状压||dfs搜索+最小生成树
- H - Kingdoms UVA - 12507——最小生成树+dfs
- 【最小生成树】UVA_12507
- Uva 11733 - Airports 最小生成森林..Kruskal
- hdu2489 Minimal Ratio Tree dfs+最小生成树
- UVA-1494 - Qin Shi Huang's National Road System(最小生成树)
- UVa 10147 Highways(最小生成树,水)
- HDU 2489 Minimal Ratio Tree (DFS枚举+最小生成树Prim)
- uva 10048 Audiophobia(最小生成树)
- uva 10034 Freckles(最小生成树Kruskal)
- UVA 10034 Freckles 最小生成树
- UVa:10397 Connect the Campus(最小生成树)
- uva 4138【最小生成树prime算法】
- uva 10397 - Connect the Campus(最小生成树&并查集)
- uva 10369 - Arctic Network(最小生成树)
- 度限制最小生成树 POJ 1639 贪心+DFS+prim
- Genghis Khan the Conqueror----HDU_4126----最小生成树_DFS_DP
- uva10034Freckles - prime最小生成树
- BZOJ 1016 [JSOI2008]最小生成树计数 dfs
- HDU 2489 Minimal Ratio Tree(dfs枚举+最小生成树)