hdu 3435 A new Graph Game
2011-07-03 16:17
405 查看
//邻接表 2859MS #include<cstdio> #include<cstring> using namespace std; const int maxn=1010*2; const int maxm=10010*10;//最大顶点数和边数 const int maxl=999999999; inline int Min(int a,int b) { return a<b?a:b; } inline int Max(int a,int b) { return a>b?a:b; } struct st { int y,d; int ne; int bro; int f; } e[maxm]; int ee; int st[maxn]; int n,m; int F; void addedge(int x,int y,int d,int f) { //给顶点x和y间添加一条费用d,流量f的边 e[ee].y=y; e[ee].d=d; e[ee].ne=st[x]; e[ee].f=f; st[x]=ee++; e[ee].y=x; e[ee].d=-1*d; e[ee].ne=st[y]; e[ee].f=0; st[y]=ee++; e[ee-2].bro=ee-1; e[ee-1].bro=ee-2; } int d[maxn],p[maxn]; //spfa所用到起点的最短距离(这里距离相当于cost)和路径记录之前的一个节点 int c[maxn];//spfa所用数组:是否在队列中 int que[maxn],head,tail;//spfa专用队列 int spfa(int sx,int ex)//求sx到ex的一次费用增广 { //如果没有增广路就返回maxl 否则返回费用 int i,j,k; for (i=0; i<maxn; i++) d[i]=maxl; memset(c,0,sizeof(c));//初始化都没进 d[sx]=0; que[head=0]=sx; tail=1; c[sx]=1; while (head!=tail) { k=que[head++]; head%=maxn; c[k]=0; for (i=st[k]; i!=-1; i=e[i].ne) if (e[i].f) if (d[k]+e[i].d<d[e[i].y]) { d[e[i].y]=d[k]+e[i].d; p[e[i].y]=i; if (c[e[i].y]==0) { c[e[i].y]=1; if (e[i].d<0) { head=(head-1+maxn)%maxn; que[head]=e[i].y; } else { que[tail++]=e[i].y; tail%=maxn; } } } } if (d[ex]==maxl) return maxl; //如果无法到达终点返回maxl k=maxl; for (i=ex; i!=sx; i=e[e[p[i]].bro].y) k=Min(k,e[p[i]].f); //计算流 //sum+=k; //sum计算流量 F+=k; for (i=ex; i!=sx; i=e[e[p[i]].bro].y) //增加反向边 { e[p[i]].f-=k; e[e[p[i]].bro].f+=k; } return d[ex]*k; //返回费用为流大小*路径长度(cost累加) } int main() { int T; int cas=1; int m; scanf("%d",&T); while(T--) { int nn,mm; scanf("%d%d",&nn,&mm); memset(st,-1,sizeof(st)); ee=0; for(int i=1; i<=mm; i++) { int x,y,c; scanf("%d%d%d",&x,&y,&c); addedge(x,y+nn,c,1); addedge(y,x+nn,c,1); } for(int i=1; i<=nn; i++) { addedge(0,i,0,1); addedge(i+nn,nn+nn+1,0,1); } n=nn*2+2; F=0; int tot=0,k; while ((k=spfa(0,n-1))!=maxl) tot+=k; //printf("%") if(F!=nn) printf("Case %d: NO\n",cas++); else printf("Case %d: %d\n",cas++,tot); } return 0; }
//c++ 2390ms
//完美匹配
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int inf=1<<28;
int g[1005][1005],lx[1005],ly[1005];//顶点标号
bool sx[1005],sy[1005];//是否已经搜索过
int link[1005],n,stack[1005];
bool path(int k)
{
sx[k]=true;
for(int i=1; i<=n; i++)
{
if(sy[i]) continue;
int t=ly[i]+lx[k]-g[k][i];
if(t==0)
{
sy[i]=1;
if(link[i]==-1||path(link[i]))
{
link[i]=k;
return true;
}
}
else if(stack[i]>t) stack[i]=t;
}
return false;
}
int BestMatch()
{
int d,sum;
memset(ly,0,sizeof(ly));
memset(link,-1,sizeof(link));
for(int i=1; i<=n; i++)
{
lx[i]=-inf;
for(int j=1; j<=n; j++)
if(lx[i]<g[i][j]&&g[i][j]!=0) lx[i]=g[i][j];
}
for(int k=1; k<=n; k++)
{
for (int i=1; i<=n; i++) stack[i]=inf;
while(1)
{
memset(sx,0,sizeof(sx));
memset(sy,0,sizeof(sy));
if(path(k)) break;
d=inf;
for(int i=1; i<=n; i++)
if (!sy[i]&&stack[i]<d) d=stack[i];
for(int i=1; i<=n; i++)
if(sx[i]) lx[i]-=d;
for(int i=1; i<=n; i++)
if(sy[i]) ly[i]+=d;
else stack[i]-=d;
}
}
sum=0;
for(int i=1; i<=n; i++)
{
if(link[i]==-1||g[link[i]][i]==-inf) return -1;
sum+=g[link[i]][i];
}
return -sum;
}
int main()
{
int T;
int cas=1;
int m;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
g[i][j]=inf;
for(int i=1; i<=m; i++)
{
int x,y,c;
scanf("%d%d%d",&x,&y,&c);
g[x][y]=g[y][x]=min(g[x][y],c);
}
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++) g[i][j]=-g[i][j];
int t=BestMatch();
if(t==-1) printf("Case %d: NO\n",cas++);
else printf("Case %d: %d\n",cas++,t);
}
return 0;
}
相关文章推荐
- HDU-3435 A new Graph Game
- HDU-3435 A new Graph Game
- [HDU 3435]A new Graph Game[拆点][KM]
- 【HDU 3435】 A new Graph Game (KM|费用流)
- HDU 3435 KM A new Graph Game
- HDU 3435 A new Graph Game(最小费用最大流)&HDU 3488
- HDU 3435 A new Graph Game
- hdu 3435 A new Graph Game KM
- hdu 3435 A new Graph Game KM
- HDU 3435 A new Graph Game
- HDU 3435 A new Graph Game(二分图最优匹配:有向环覆盖)
- HDU 3435 A new Graph Game(KM完美匹配)
- HDU 3435 A new Graph Game
- hdu 1853 Cyclic Tour && hdu 3435 A new Graph Game(简单KM算法)
- HDU 3435 A new Graph Game 费用流
- hdu 3435 A new Graph Game
- HDU 3435 A new Graph Game(费用流)
- hdu 3435 A new Graph Game(最小费用流)
- HDU 3435 A new Graph Game(二分图最优匹配:有向环覆盖)
- HDU 3435 A new Graph Game