【Usaco2008 Oct 资格赛】灌水 和 Islands and Bridges
来源:互联网 发布:图像拼接算法apap 编辑:程序博客网 时间:2024/06/05 05:01
Description
Farmer John已经决定把水灌到他的n(1<=n<=300)块农田,农田被数字1到n标记。把一块土地进行灌水有两种方法,从其他农田饮水,或者这块土地建造水库。
建造一个水库需要花费wi(1<=wi<=100000),连接两块土地需要花费Pij(1<=pij<=100000,pij=pji,pii=0).
计算Farmer John所需的最少代价。
Input
*第一行:一个数n
*第二行到第n+1行:第i+1行含有一个数wi
*第n+2行到第2n+1行:第n+1+i行有n个被空格分开的数,第j个数代表pij。
Output
*第一行:一个单独的数代表最小代价.
分析
其实就是类似于要求选点使得这个图连通的选法中的代价最小,所以是最小生成树,
当然还要在用0向每个点连一条每个单独的费用,即可解决这个问题了。
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<algorithm>#define ll long longusing namespace std;const int N=305;struct note{ ll a,b,c;}a[N*N];ll x,n,fa[N],gx,gy;bool cmp(note x,note y){ return x.c<y.c;}int getfa(int x){ if (!fa[x]) return x; else { fa[x]=getfa(fa[x]); return fa[x]; }}int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&x); a[i].a=0; a[i].b=i; a[i].c=x; } int tot=n; for(int i=1;i<=n;i++){ for(int j=1;j<=i;j++) scanf("%d",&x); for(int j=i+1;j<=n;j++){ scanf("%d",&x); a[++tot].a=i; a[tot].b=j;a[tot].c=x; } scanf("\n"); } sort(a+1,a+tot+1,cmp); ll ans=0; for(int i=1;i<=tot;i++){ gx=getfa(a[i].a);gy=getfa(a[i].b); if (gx!=gy){ ans+=a[i].c; fa[gx]=gy; } } printf("%d",ans);}
Islands and Bridges
Description
给定一些岛屿和一些连接岛屿的桥梁,大家都知道汉密尔顿路是访问每个岛屿一次的路线,在我们这个地图中,每个岛屿有个正整数的权值,表示这个岛屿的观赏价值。假设一共有N个岛屿,用Vi表示岛屿Ci的价值,汉密尔顿路C1C2….Cn的价值是以下三部分的总和:
(1)所有岛屿的价值之和;
(2)对于路径中相邻的两个岛屿CiCi+1,把两个岛屿的价值之积加到总价值中;
(3)路径中连续三个岛屿CiCi+1Ci+2,如果Ci与Ci+2有桥直接相连,则把这三个岛屿价值之积加到总价值中。
要求计算汉密尔顿路最大的价值以及方案数。
Input
输入第一行是一个整数Q(Q<=20),表示测试数据的数量。每个测试数据第一行输入两个整数N和M,分别表示岛屿数和桥梁数,接下来一行包含N个正整数,第i个数表示Vi,每个数不超过100,最后M行,每行两个数X,Y,表示岛X和岛Y之间有一座桥直接相连,桥是双向的,岛屿编号为1到N(N<=13)
Output
对于每个测试数据,输出一行,两个整数,第一个数表示最大价值,第二个数表示方案数,如果不存在汉密尔顿路径,输出“0 0”
注意:一条路径可以反着走,我们认为这两条路径是同一条路径。
分析
这题比较简单,就不多说了。
设f[i][j][k]表示i为状态,最后的是j,倒数第二的是k的最大值。
直接维护即可。
但是注意开long long
而且要注意特殊情况,n=1
所以这考的是细心和耐心,而若不细心就会前功尽弃了,白白打这程序了
#include<iostream>#include<cmath>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#define ll long longusing namespace std;const int N=14;ll t,n,m,x,y,a[N][N];ll ans,sum,num[N][N],f[1<<N][N][N],g[1<<N][N][N],no,v[N],c[N+2]; int main(){ scanf("%d",&t); c[0]=1; for(int i=1;i<=N;i++)c[i]=c[i-1]*2; for(;t;t--){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) a[i][0]=0; memset(num,0,sizeof(num)); memset(f,0,sizeof(f)); memset(g,0,sizeof(g)); for(int i=1;i<=n;i++) scanf("%d",&v[i]); for(int i=1;i<=m;i++){ scanf("%d %d",&x,&y); if (x==y) continue; if (!num[x][y]) a[x][++a[x][0]]=y,a[y][++a[y][0]]=x; num[x][y]++;num[y][x]++; } for(int i=1;i<=n;i++) for(int j=1,k=a[i][1];j<=a[i][0];j++,k=a[i][j]){ int toe=(1<<(i-1))+(1<<(a[i][j]-1)); f[toe][i][k]=v[k]*v[i]+v[i]+v[k], g[toe][i][k]=num[k][i]; } for(int i=0;i<=c[n]-1;i++) for(int st=1;st<=n;st++) if (i&(c[st-1])) for(int en=1;en<=n;en++) if (i&(c[en-1])&&(g[i][st][en])){ for(int k=1,j=a[en][1];k<=a[en][0];k++,j=a[en][k]){ if (!(i&c[j-1])){ int oi=f[i+c[j-1]][en][j]; if (num[st][j]) no=v[j]*v[st]*v[en];else no=0; if (oi<f[i][st][en]+v[j]+no+v[j]*v[en]){ f[i+c[j-1]][en][j]=f[i][st][en]+v[j]+no+v[j]*v[en]; g[i+c[j-1]][en][j]=g[i][st][en]*num[j][en]; }else if (oi==f[i][st][en]+v[j]+no+v[j]*v[en]){ g[i+c[j-1]][en][j]+=g[i][st][en]*num[j][en]; } } } } ans=0,sum=0; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if (g[c[n]-1][i][j]){ if (ans<f[c[n]-1][i][j]) ans=f[c[n]-1][i][j],sum=g[c[n]-1][i][j]; else if (ans==f[c[n]-1][i][j]) sum+=g[c[n]-1][i][j]; } if (n==1) { printf("%d 1\n",v[1]); }else printf("%lld %lld\n",ans,sum/2); }}
- 【Usaco2008 Oct 资格赛】灌水 和 Islands and Bridges
- [Bzoj1601][Usaco2008 Oct]灌水
- bzoj1601 [Usaco2008 Oct]灌水
- [BZOJ1601] [Usaco2008 Oct]灌水
- [BZOJ1601][Usaco2008 Oct]灌水
- bzoj1601[Usaco2008 Oct]灌水
- bzoj1601【Usaco2008 Oct】灌水
- [Usaco2008 Oct]灌水(MST)
- BZOJ1601: [Usaco2008 Oct]灌水
- bzoj1601[Usaco2008 Oct]灌水
- 1601: [Usaco2008 Oct]灌水
- [bzoj1601][Usaco2008 Oct]灌水
- bzoj1601 [Usaco2008 Oct]灌水
- BZOJ1601: [Usaco2008 Oct]灌水
- bzoj1601: [Usaco2008 Oct]灌水
- BZOJ 1601 [Usaco2008 Oct]灌水
- bzoj 1601 [Usaco2008 Oct]灌水
- bzoj 1601: [Usaco2008 Oct]灌水
- Java字符转C的思路
- STM32 堆和栈的学习(二)
- nyoj571 整数划分(三)
- JNI 方法
- js原型(2)
- 【Usaco2008 Oct 资格赛】灌水 和 Islands and Bridges
- express + redis 构建基于node的开发环境
- 单例模式
- vim插件管理工具apt-vim
- 【NOI2001】炮兵阵地
- JNI——在C中输出日志
- WPF之Binding深入探讨
- poi合并单元格
- 在C语言中调用Java方法获取方法签名