标签:hdu 1853 cyclic tour 二分图最小权问题
6 9 1 2 5 2 3 5 3 1 10 3 4 12 4 1 8 4 6 11 5 4 7 5 6 9 6 5 4 6 5 1 2 1 2 3 1 3 4 1 4 5 1 5 6 1
42 -1HintIn the first sample, there are two cycles, (1->2->3->1) and (6->5->4->6) whose length is 20 + 22 = 42.
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <string> #include <map> #include <stack> #include <vector> #include <set> #include <queue> #pragma comment (linker,"/STACK:102400000,102400000") #define maxn 1005 #define MAXN 2005 #define mod 1000000009 #define INF 0x3f3f3f3f #define pi acos(-1.0) #define eps 1e-6 #define lson rt<<1,l,mid #define rson rt<<1|1,mid+1,r #define FRE(i,a,b) for(i = a; i <= b; i++) #define FREE(i,a,b) for(i = a; i >= b; i--) #define FRL(i,a,b) for(i = a; i < b; i++) #define FRLL(i,a,b) for(i = a; i > b; i--) #define mem(t, v) memset ((t) , v, sizeof(t)) #define sf(n) scanf("%d", &n) #define sff(a,b) scanf("%d %d", &a, &b) #define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c) #define pf printf #define DBG pf("Hi\n") typedef long long ll; using namespace std; /* KM算法 O(nx*nx*ny) 求最大权匹配(最佳匹配) 若求最小权匹配,可将权值取相反数,结果取相反数 点的标号从0开始 */ const int N=110; int nx,ny; //两边的点数 int g[N][N]; //二分图描述,g赋初值为-INF int linker[N],lx[N],ly[N]; //y 中各点匹配状态,x,y中的点的标号 int slack[N]; bool visx[N],visy[N]; bool flag; bool DFS(int x) { visx[x]=true; for (int y=0;y<ny;y++) { if (visy[y]) continue; int tmp=lx[x]+ly[y]-g[x][y]; if (tmp==0) { visy[y]=true; if (linker[y]==-1||DFS(linker[y])) { linker[y]=x; return true; } } else if (slack[y]>tmp) slack[y]=tmp; } return false; } int KM() { flag=true; memset(linker,-1,sizeof(linker)); memset(ly,0,sizeof(ly)); for (int i=0;i<nx;i++) //赋初值,lx置为最大值 { lx[i]=-INF; for (int j=0;j<ny;j++) { if (g[i][j]>lx[i]) lx[i]=g[i][j]; } } for (int x=0;x<nx;x++) { for (int i=0;i<ny;i++) slack[i]=INF; while (true) { memset(visx,false,sizeof(visx)); memset(visy,false,sizeof(visy)); if (DFS(x)) break; int d=INF; for (int i=0;i<ny;i++) if (!visy[i]&&d>slack[i]) d=slack[i]; for (int i=0;i<nx;i++) if (visx[i]) lx[i]-=d; for (int i=0;i<ny;i++) { if (visy[i]) ly[i]+=d; else slack[i]-=d; } } } int res=0; for (int i=0;i<ny;i++) { if (linker[i]==-1||g[linker[i]][i]<=-INF) //有的点不能匹配的话return-1 { flag=false; break; } res+=g[linker[i]][i]; } return res; } int n,m; int main() { #ifndef ONLINE_JUDGE freopen("C:/Users/asus1/Desktop/IN.txt","r",stdin); #endif int i,j; while (~sff(n,m)) { for (i=0;i<=n;i++) for (j=0;j<=n;j++) g[i][j]=-INF; nx=ny=n; int u,v,w; for (i=0;i<m;i++) { sfff(u,v,w); u--; v--; if (-w>g[u][v]) g[u][v]=-w; } int ans=KM(); ans=-ans; if (!flag) pf("-1\n"); else pf("%d\n",ans); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
Cyclic Tour (hdu 1853 二分图最小权问题)
标签:hdu 1853 cyclic tour 二分图最小权问题
原文地址:http://blog.csdn.net/u014422052/article/details/46761341