http://philoscience.iteye.com/blog/1754498 讲解
讲的很详细很好
HDU 2255
#include <iostream> #include <cstring> #define maxnum 305 #define INF (1<<31)-1 using namespace std; int vx[maxnum],vy[maxnum]; int link[maxnum]; int head[maxnum]; int lx[maxnum],ly[maxnum]; int w[maxnum][maxnum]; int slack[maxnum]; int cnt; int nx,ny; void init() { cnt = 0; memset(link,-1,sizeof(link)); memset(lx,0,sizeof(lx)); memset(ly,0,sizeof(ly)); } int find(int x) { vx[x] = 1; for(int y=0;y<ny;y++) { if(vy[y]) continue; int t = lx[x]+ly[y]-w[x][y]; if(t == 0) { vy[y] = 1; if(link[y] == -1 || find(link[y])) { link[y] =x; return 1; } } else if(slack[y] > t) slack[y] = t; } return 0; } int KM() { int i,j; for(i=0;i<nx;i++) { for(j=0;j<ny;j++) if(lx[i] < w[i][j]) lx[i] = w[i][j]; } for(int x=0;x<nx;x++) { for(i=0;i<ny;i++) slack[i] = INF; while(1) { memset(vx,0,sizeof(vx)); memset(vy,0,sizeof(vy)); if(find(x)) break; int d = INF; for(i=0;i<ny;i++) { if(!vy[i] && d > slack[i]) d = slack[i]; } for(i=0;i<nx;i++) { if(vx[i]) lx[i] -= d; } for(i=0;i<ny;i++) { if(vy[i]) ly[i] += d; else slack[i] -= d; } } } int res = 0; for(i=0;i<ny;i++) { if(link[i] > -1) res += w[link[i]][i]; } return res; } int main() { int i,j,k,kk; int a,b; int len; int u,v; int p,n,N,m; while(~scanf("%d",&n)) { nx = ny = n; init(); for(i=0;i<n;i++) { for(j=0;j<n;j++) { scanf("%d",&w[i][j]); } } printf("%d\n",KM()); } return 0; }
#include <iostream> #include <cstring> #define maxnum 205 #define INF (1<<31)-1 using namespace std; int vx[maxnum],vy[maxnum]; int link[maxnum]; int head[maxnum]; int lx[maxnum],ly[maxnum]; int w[maxnum][maxnum]; int slack[maxnum]; int cnt; int nx,ny; struct node { int x,y; }man[maxnum],house[maxnum]; void init() { cnt = 0; memset(link,-1,sizeof(link)); memset(lx,0,sizeof(lx)); memset(ly,0,sizeof(ly)); } int find(int x) { vx[x] = 1; for(int y=0;y<ny;y++) { if(vy[y]) continue; int t = lx[x]+ly[y]-w[x][y]; if(t == 0) { vy[y] = 1; if(link[y] == -1 || find(link[y])) { link[y] =x; return 1; } } else if(slack[y] > t) slack[y] = t; } return 0; } int KM() { int i,j; for(i=0;i<nx;i++) { for(j=0;j<ny;j++) if(lx[i] < w[i][j]) lx[i] = w[i][j]; } for(int x=0;x<nx;x++) { for(i=0;i<ny;i++) slack[i] = INF; while(1) { memset(vx,0,sizeof(vx)); memset(vy,0,sizeof(vy)); if(find(x)) break; int d = INF; for(i=0;i<ny;i++) { if(!vy[i] && d > slack[i]) d = slack[i]; } for(i=0;i<nx;i++) { if(vx[i]) lx[i] -= d; } for(i=0;i<ny;i++) { if(vy[i]) ly[i] += d; else slack[i] -= d; } } } int res = 0; for(i=0;i<ny;i++) { if(link[i] > -1) res += w[link[i]][i]; } return res*(-1); } int main() { int i,j,k,kk; int a,b; int len; int u,v; int p,n,N,m; char c; while(~scanf("%d%d%*c",&n,&m),n&&m) { init(); k = kk = 0; for(i=0;i<n;i++) { for(j=0;j<m;j++) { scanf("%c",&c); if(c == 'm') { man[k].x = i; man[k++].y = j; } else { if(c == 'H') { house[kk].x = i; house[kk++].y = j; } } } getchar(); } for(i=0;i<k;i++) { for(j=0;j<k;j++) { w[i][j] = abs(man[i].x - house[j].x) + abs(man[i].y - house[j].y); w[i][j] *= (-1); } } nx = ny = k; printf("%d\n",KM()); } return 0; }
#include <iostream> #include <cstring> #define maxnum 205 #define INF 0x5f5f5f using namespace std; int vx[maxnum],vy[maxnum]; int link[maxnum]; int head[maxnum]; int lx[maxnum],ly[maxnum]; int w[maxnum][maxnum]; int slack[maxnum]; int nx,ny; void init() { memset(link,-1,sizeof(link)); memset(ly,0,sizeof(ly)); } int find(int x) { vx[x] = 1; for(int y=1;y<=ny;y++) { if(vy[y]) continue; int t = lx[x]+ly[y]-w[x][y]; if(t == 0) { vy[y] = 1; if(link[y] == -1 || find(link[y])) { link[y] = x; return 1; } } else if(slack[y] > t) slack[y] = t; } return 0; } int KM() { int i,j; for(i=1;i<=nx;i++) { lx[i] = -INF; for(j=1;j<=ny;j++) if(lx[i] < w[i][j]) lx[i] = w[i][j]; } for(int x=1;x<=nx;x++) { for(i=1;i<=ny;i++) slack[i] = INF; while(1) { memset(vx,0,sizeof(vx)); memset(vy,0,sizeof(vy)); if(find(x)) break; int d = INF; for(i=1;i<=ny;i++) { if(!vy[i] && d > slack[i]) d = slack[i]; } for(i=1;i<=nx;i++) { if(vx[i]) lx[i] -= d; } for(i=1;i<=ny;i++) { if(vy[i]) ly[i] += d; else slack[i] -= d; } } } int res = 0; for(i=1;i<=ny;i++) { if(link[i] == -1 || w[link[i]][i] == -INF) return 1; else res += w[link[i]][i]; } return res; } int main() { int i,j,k,kk; int a,b,c; int len; int u,v; int p,n,N,m; while(~scanf("%d%d",&n,&m)) { init(); for(i=1;i<=n;i++) for(j=1;j<=n;j++) w[i][j] = -INF; for(i=0;i<m;i++) { scanf("%d%d%d",&a,&b,&c); if(w[a][b] < -c) w[a][b] = -c; } nx = ny = n; printf("%d\n",-KM()); } return 0; }
HDU 3488
#include <iostream> #include <cstring> #define maxnum 205 #define INF 0x5f5f5f using namespace std; int vx[maxnum],vy[maxnum]; int link[maxnum]; int head[maxnum]; int lx[maxnum],ly[maxnum]; int w[maxnum][maxnum]; int slack[maxnum]; int nx,ny; void init() { memset(link,-1,sizeof(link)); memset(ly,0,sizeof(ly)); } int find(int x) { vx[x] = 1; for(int y=1;y<=ny;y++) { if(vy[y]) continue; int t = lx[x]+ly[y]-w[x][y]; if(t == 0) { vy[y] = 1; if(link[y] == -1 || find(link[y])) { link[y] = x; return 1; } } else if(slack[y] > t) slack[y] = t; } return 0; } int KM() { int i,j; for(i=1;i<=nx;i++) { lx[i] = -INF; for(j=1;j<=ny;j++) if(lx[i] < w[i][j]) lx[i] = w[i][j]; } for(int x=1;x<=nx;x++) { for(i=1;i<=ny;i++) slack[i] = INF; while(1) { memset(vx,0,sizeof(vx)); memset(vy,0,sizeof(vy)); if(find(x)) break; int d = INF; for(i=1;i<=ny;i++) { if(!vy[i] && d > slack[i]) d = slack[i]; } for(i=1;i<=nx;i++) { if(vx[i]) lx[i] -= d; } for(i=1;i<=ny;i++) { if(vy[i]) ly[i] += d; else slack[i] -= d; } } } int res = 0; for(i=1;i<=ny;i++) { if(link[i] == -1 || w[link[i]][i] == -INF) return 1; else res += w[link[i]][i]; } return res; } int main() { int i,j,k,kk; int a,b,c; int len; int u,v; int p,n,N,m; scanf("%d",&N); while(N--) { init(); scanf("%d%d",&n,&m); for(i=1;i<=n;i++) for(j=1;j<=n;j++) w[i][j] = -INF; for(i=0;i<m;i++) { scanf("%d%d%d",&a,&b,&c); if(w[a][b] < -c) w[a][b] = -c; } nx = ny = n; printf("%d\n",-KM()); } return 0; }
#include <iostream> #include <cstring> #define maxnum 1050 #define INF 0x5f5f5f using namespace std; int vx[maxnum],vy[maxnum]; int link[maxnum]; int head[maxnum]; int lx[maxnum],ly[maxnum]; int w[maxnum][maxnum]; int slack[maxnum]; int nx,ny; void init() { memset(link,-1,sizeof(link)); memset(ly,0,sizeof(ly)); } int find(int x) { vx[x] = 1; for(int y=1;y<=ny;y++) { if(vy[y]) continue; int t = lx[x]+ly[y]-w[x][y]; if(t == 0) { vy[y] = 1; if(link[y] == -1 || find(link[y])) { link[y] = x; return 1; } } else if(slack[y] > t) slack[y] = t; } return 0; } int KM() { int i,j; for(i=1;i<=nx;i++) { lx[i] = -INF; for(j=1;j<=ny;j++) if(lx[i] < w[i][j]) lx[i] = w[i][j]; } for(int x=1;x<=nx;x++) { for(i=1;i<=ny;i++) slack[i] = INF; while(1) { memset(vx,0,sizeof(vx)); memset(vy,0,sizeof(vy)); if(find(x)) break; int d = INF; for(i=1;i<=ny;i++) { if(!vy[i] && d > slack[i]) d = slack[i]; } for(i=1;i<=nx;i++) { if(vx[i]) lx[i] -= d; } for(i=1;i<=ny;i++) { if(vy[i]) ly[i] += d; else slack[i] -= d; } } } int res = 0; for(i=1;i<=ny;i++) { if(link[i] == -1 || w[link[i]][i] == -INF) return 1; else res += w[link[i]][i]; } return res; } int main() { int i,j,k,kk; int a,b,c; int len; int u,v; int p,n,N,m; scanf("%d",&N); k=1; while(N--) { init(); scanf("%d%d",&n,&m); for(i=1;i<=n;i++) for(j=1;j<=n;j++) w[i][j] = -INF; for(i=0;i<m;i++) { scanf("%d%d%d",&a,&b,&c); if(w[a][b] < -c) w[a][b] = -c; if(w[b][a] < -c) w[b][a] = -c; } nx = ny = n; int t = KM(); printf("Case %d: ",k++); printf(t>0?"NO\n":"%d\n",-t); } return 0; }
#include <iostream> #include <cstring> #define maxnum 1050 #define INF 0x5f5f5f using namespace std; int vx[maxnum],vy[maxnum]; int link[maxnum],linkx[maxnum]; int head[maxnum]; int lx[maxnum],ly[maxnum]; int w[maxnum][maxnum]; int slack[maxnum]; int nx,ny; void init() { memset(link,-1,sizeof(link)); memset(linkx,0,sizeof(linkx)); memset(lx,0,sizeof(lx)); memset(ly,0,sizeof(ly)); } int find(int x) { vx[x] = 1; for(int y=1;y<=ny;y++) { if(vy[y]) continue; int t = lx[x]+ly[y]-w[x][y]; if(t == 0) { vy[y] = 1; if(link[y] == -1 || find(link[y])) { link[y] = x; return 1; } } else if(slack[y] > t) slack[y] = t; } return 0; } int KM() { int i,j; for(i=1;i<=nx;i++) { lx[i] = -INF; for(j=1;j<=ny;j++) if(lx[i] < w[i][j]) lx[i] = w[i][j]; } for(int x=1;x<=nx;x++) { for(i=1;i<=ny;i++) slack[i] = INF; while(1) { memset(vx,0,sizeof(vx)); memset(vy,0,sizeof(vy)); if(find(x)) break; int d = INF; for(i=1;i<=ny;i++) { if(!vy[i] && d > slack[i]) d = slack[i]; } for(i=1;i<=nx;i++) { if(vx[i]) lx[i] -= d; } for(i=1;i<=ny;i++) { if(vy[i]) ly[i] += d; else slack[i] -= d; } } } int res = 0; for(i=1;i<=ny;i++) { if(link[i] > -1 && w[link[i]][i] != -INF) { res += w[link[i]][i]; linkx[link[i]] = 1; } } for(i=1;i<=nx;i++) if(!linkx[i]) return -1; return res; } int main() { int i,j,k,kk; int a,b,c; int len; int u,v; int p,n,N,m; kk=1; while(~scanf("%d%d%d",&n,&m,&k)) { init(); for(i=1;i<=n;i++) for(j=1;j<=m;j++) w[i][j] = -INF; for(i=0;i<k;i++) { scanf("%d%d%d",&a,&b,&c); if(c < 0) continue; w[a+1][b+1] = c; } nx=n;ny=m; printf("Case %d: ",kk++); if(k==0) printf("-1\n"); else printf("%d\n",KM()); } return 0; }
#include <iostream> #include <cstring> #define maxnum 1050 #define INF 0xffff5f using namespace std; int vx[maxnum],vy[maxnum],vis[maxnum]; int link[maxnum]; int head[maxnum]; int lx[maxnum],ly[maxnum]; int w[maxnum][maxnum]; int slack[maxnum]; int nx,ny; int change; void init() { memset(link,-1,sizeof(link)); memset(lx,0,sizeof(lx)); memset(ly,0,sizeof(ly)); memset(vis,0,sizeof(vis)); change = 0; } int find(int x) { vx[x] = 1; for(int y=1;y<=ny;y++) { if(vy[y]) continue; int t = lx[x]+ly[y]-w[x][y]; if(t == 0) { vy[y] = 1; if(link[y] == -1 || find(link[y])) { link[y] = x; return 1; } } else if(slack[y] > t) slack[y] = t; } return 0; } int KM() { int i,j; for(i=1;i<=nx;i++) { for(j=1;j<=ny;j++) if(lx[i] < w[i][j]) lx[i] = w[i][j]; } for(int x=1;x<=nx;x++) { for(i=1;i<=ny;i++) slack[i] = INF; while(1) { memset(vx,0,sizeof(vx)); memset(vy,0,sizeof(vy)); if(find(x)) break; int d = INF; for(i=1;i<=ny;i++) { if(!vy[i] && d > slack[i]) d = slack[i]; } for(i=1;i<=nx;i++) { if(vx[i]) lx[i] -= d; } for(i=1;i<=ny;i++) { if(vy[i]) ly[i] += d; else slack[i] -= d; } } } int res = 0; for(i=1;i<=ny;i++) { if(link[i] > -1) { // if(link[i] != vis[i]) // change++; res += w[link[i]][i]; } } return res; } int main() { int i,j,k,kk; int a,b,c; int len; int u,v; int p,n,N,m; int sum; while(~scanf("%d%d",&n,&m)) { init(); for(i=1;i<=n;i++) for(j=1;j<=m;j++) { scanf("%d",&w[i][j]); w[i][j] *= 100; } for(i=1,sum=0;i<=n;i++) { scanf("%d",&k); sum += w[i][k]; w[i][k]++; } nx=n;ny=m; kk = KM(); printf("%d %d\n",n-kk%100,kk/100-sum/100); } return 0; }