二分匹配 大白例题虽有代码
所有代码:
UVALIVE 4043 Ants
#include <map> #include <set> #include <list> #include <cmath> #include <ctime> #include <deque> #include <stack> #include <queue> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <climits> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #define LL long long #define PI 3.1415926535897932626 using namespace std; int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);} const int MAXN = 210; const int MAXM = MAXN * MAXN * 2; const double INF = 1e18; const double eps = 1e-10; int nx,ny; double g[MAXN][MAXN]; int linker[MAXN]; double lx[MAXN],ly[MAXN]; double slack[MAXN]; bool visx[MAXN],visy[MAXN]; bool dfs(int x) { visx[x] = true; for (int y = 0 ; y < ny ; y++) { if (visy[y]) continue; double tmp = lx[x] + ly[y] - g[x][y]; if (fabs(tmp - 0.0) < eps) { visy[y] = true; if (linker[y] == -1 || dfs(linker[y])) { linker[y] = x; return true; } } else if (slack[y] - tmp > eps) slack[y] = tmp; } return false; } double KM() { memset(linker,-1,sizeof(linker)); for (int i = 0 ; i < MAXN ; i++) ly[i] = 0.0; for (int i = 0 ; i < nx ; i++) { lx[i] = -INF; for (int j = 0 ; j < ny ; j++) if (g[i][j] - lx[i] > eps) 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; double d = INF; for (int i = 0 ; i < ny ; i++) { if (!visy[i] && d - slack[i] > eps) 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; } } } double ret = 0; for (int i = 0 ; i < ny ; i++) if (linker[i] != -1) ret += g[linker[i]][i]; return ret; } struct point { double x,y; }white[MAXN],black[MAXN]; int N; int main() { bool first = true; while (scanf("%d",&N) != EOF) { if (first) first = false; else putchar('\n'); for (int i = 0 ; i < N ; i++) scanf("%lf%lf",&white[i].x,&white[i].y); for (int i = 0 ; i < N ; i++) scanf("%lf%lf",&black[i].x,&black[i].y); nx = ny = N; for (int i = 0 ; i < N ; i++) { for (int j = 0 ; j < N ; j++) { double dis = sqrt((white[i].x - black[j].x) * (white[i].x - black[j].x) + (white[i].y - black[j].y) * (white[i].y - black[j].y)); g[j][i] = -1.0 * dis; } } KM(); for (int i = 0 ; i < N ; i++) printf("%d\n",linker[i] + 1); } return 0; }
UVA 11383 Golden Tiger Claw
#include <map> #include <set> #include <list> #include <cmath> #include <ctime> #include <deque> #include <stack> #include <queue> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <climits> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #define LL long long #define PI 3.1415926535897932626 using namespace std; int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);} const int MAXN = 510; const int INF = 0x3f3f3f3f; int nx,ny; int N; int g[MAXN][MAXN]; int w[MAXN][MAXN]; int linker[MAXN],lx[MAXN],ly[MAXN]; int slack[MAXN]; bool visx[MAXN],visy[MAXN]; 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() { memset(linker,-1,sizeof(linker)); memset(ly,0,sizeof(ly)); for (int i = 0 ; i < nx ; i++) { 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 ret = 0; for (int i = 0 ; i < ny ; i++) if (linker[i] != -1) ret += g[linker[i]][i]; return ret; } int main() { while (scanf("%d",&N) != EOF) { for (int i = 0; i < N ; i++) for (int j = 0 ; j < N ; j++) scanf("%d",&g[i][j]); nx = N; ny = N; KM(); for (int i = 0 ; i < N ; i++) printf("%d%c",lx[i],i == N - 1 ? '\n' : ' '); for (int i = 0 ; i < N ; i++) printf("%d%c",ly[i],i == N - 1 ? '\n' : ' '); int ret = 0; for (int i = 0 ; i < N ; i++) ret += lx[i] + ly[i]; printf("%d\n",ret); } return 0; }
UVALIVE 2238 Fixed Partition Memory Management
Final题就是不一样!
#include <map> #include <set> #include <list> #include <cmath> #include <ctime> #include <deque> #include <stack> #include <queue> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <climits> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #define LL int #define PI 3.1415926535897932626 using namespace std; int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);} const int MAXN = 600; const int MAXD = 600; const int INF = 0x3f3f3f3f; int nx,ny; int g[MAXN][MAXN]; int w[MAXN][MAXN]; int linker[MAXN],lx[MAXN],ly[MAXN]; int slack[MAXN]; bool visx[MAXN],visy[MAXN]; 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() { memset(linker,-1,sizeof(linker)); memset(ly,0,sizeof(ly)); for (int i = 0 ; i < nx ; i++) { 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 ret = 0; for (int i = 0 ; i < ny ; i++) if (linker[i] != -1) ret += g[linker[i]][i]; return ret; } int N,M; int support[MAXD]; pair<int,int>id[MAXD]; int dis[MAXD][MAXD]; struct node { int cnt; int S[20],T[20]; }src[MAXD]; void read() { for (int i = 0 ; i < M ; i++) scanf("%d",&support[i]); for (int i = 0 ; i < N ; i++) { scanf("%d",&src[i].cnt); for (int j = 0 ; j < src[i].cnt ; j++) scanf("%d%d",&src[i].S[j],&src[i].T[j]); } } void build() { for (int i = 0 ; i < N ; i++) { for (int j = 0 ; j < M ; j++) { int tmp; if (support[j] < src[i].S[0]) tmp = INF; else { int pos; for (pos = 0 ; pos < src[i].cnt ; pos++) { if (src[i].S[pos] > support[j]) break; } pos--; tmp = src[i].T[pos]; } dis[i][j] = tmp; for (int k = 0 ; k < N ; k++) { if (tmp == INF) g[i][j * N + k] = -INF; else g[i][j * N + k] = -1LL * (k + 1) * tmp; id[j * N + k] = make_pair(j,k); } } } } set<pair<int,int> >s[20]; pair<int,int>ret[60]; set<pair<int,int> >::iterator it,temp; void output(int kase) { printf("Case %d\n",kase); for (int i = 0 ; i < 20 ; i++) s[i].clear(); for (int i = 0 ; i < N * M ; i++) { if (linker[i] == -1) continue; else { int memory = id[i].first,idx = id[i].second; s[memory].insert(make_pair(idx,linker[i])); } } for (int i = 0 ; i < M ; i++) { if (s[i].empty()) continue; int sum = 0; it = s[i].end(); it--; for (;;it--) { int pos = (*it).second; int order = (*it).first; ret[pos] = make_pair(i,sum); sum += dis[pos][i]; if (it == s[i].begin()) break; } } double sum = 0.0; for(int i = 0 ; i < N ; i++) sum += lx[i]; for (int i = 0 ; i < N * M ; i++) sum += ly[i]; printf("Average turnaround time = %.2lf\n",fabs(sum / N)); for (int i = 0 ; i < N ; i++) { printf("Program %d runs in region %d from %d to %d\n",i + 1,ret[i].first + 1, ret[i].second,ret[i].second + dis[i][ret[i].first]); } putchar('\n'); } int main() { int kase = 1; while (scanf("%d%d",&M,&N) != EOF) { if (M == 0 && N == 0) break; read(); build(); nx = N; ny = N * M; KM(); output(kase); kase++; } return 0; }
UVALIVE 3989 Ladies' Choice
#include <map> #include <set> #include <list> #include <cmath> #include <ctime> #include <deque> #include <stack> #include <queue> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <climits> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #define LL long long #define PI 3.1415926535897932626 using namespace std; int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);} const int MAXN = 1010; int pref[MAXN][MAXN],order[MAXN][MAXN],next[MAXN]; int future_husband[MAXN],future_wife[MAXN]; queue<int>q; void engage(int man,int woman) { int m = future_husband[woman]; if (m) { future_wife[m] = 0; q.push(m); } future_husband[woman] = man; future_wife[man] = woman; } int main() { int T; scanf("%d",&T); while (T--) { int N; scanf("%d",&N); for (int i = 1 ; i <= N ; i++) { for (int j = 1 ; j <= N ; j++) scanf("%d",&pref[i][j]); next[i] = 1; future_wife[i] = 0; q.push(i); } for (int i = 1 ; i <= N ; i++) { for (int j = 1 ; j <= N ; j++) { int x; scanf("%d",&x); order[i][x] = j; } future_husband[i] = 0; } while (!q.empty()) { int man = q.front(); q.pop(); int woman = pref[man][next[man]++]; if (!future_husband[woman]) engage(man,woman); else if (order[woman][man] < order[woman][future_husband[woman]]) engage(man,woman); else q.push(man); } while (!q.empty()) q.pop(); for (int i = 1; i <= N ; i++) printf("%d\n",future_wife[i]); if (T) putchar('\n'); } return 0; }
UVA 11419 SAM I AM
感觉还是不理解啥是匈牙利树。。
#include <map> #include <set> #include <list> #include <cmath> #include <ctime> #include <deque> #include <stack> #include <queue> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <climits> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #define LL long long #define PI 3.1415926535897932626 using namespace std; int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);} const int MAXN = 1010; const int MAXM = MAXN * MAXN * 2; const int INF = 0x3f3f3f3f; struct Edge { int u,v,w; int next; }edge[MAXM]; int head[MAXN],tot; void init() { memset(head,-1,sizeof(head)); tot = 0; } void add_edge(int u,int v,int w) { edge[tot].u = u; edge[tot].v = v; edge[tot].w = w; edge[tot].next = head[u]; head[u] = tot++; } int linker[MAXN],rlinker[MAXN]; bool used[MAXN]; int UN; bool dfs(int u) { for (int i = head[u]; i != -1 ; i = edge[i].next) { int v = edge[i].v; if (!used[v]) { used[v] = true; if(linker[v] == -1 || dfs(linker[v])) { linker[v] = u; rlinker[u] = v; return true; } } } return false; } bool visu[MAXN],visv[MAXN]; bool inu[MAXN],inv[MAXN]; bool calcu(int u) { visu[u] = true; for (int i = head[u] ; i != -1 ; i = edge[i].next) { int v = edge[i].v; if (!visv[v]) { visv[v] = true; if (linker[v] == -1 || calcu(linker[v])) return true; } } return false; } int NX,NY,M; int main() { while (scanf("%d%d%d",&NX,&NY,&M) != EOF) { if (NX == 0 && NY == 0 && M == 0) break; init(); memset(visu,false,sizeof(visu)); memset(visv,false,sizeof(visv)); memset(inu,false,sizeof(inu)); memset(inv,false,sizeof(inv)); memset(linker,-1,sizeof(linker)); memset(rlinker,-1,sizeof(rlinker)); for (int i = 0 ; i < M ; i++) { int x,y; scanf("%d%d",&x,&y); x--; y--; add_edge(x,y,9797); inu[x] = true; inv[y] = true; } int ret = 0; for (int i = 0 ; i < NX ; i++) { memset(used,false,sizeof(used)); if (dfs(i)) ret++; } printf("%d",ret); for (int i = 0 ; i < NX ; i++) if (rlinker[i] == -1) calcu(i); for (int i = 0 ; i < NX ; i++) if (inu[i] && !visu[i]) printf(" r%d",i + 1); for (int i = 0 ; i < NY ; i++) if (inv[i] && visv[i]) printf(" c%d",i + 1); putchar('\n'); } return 0; }
UVALIVE 3415 Guardian of Decency
#include <map> #include <set> #include <list> #include <cmath> #include <ctime> #include <deque> #include <stack> #include <queue> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <climits> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #define LL long long #define PI 3.1415926535897932626 using namespace std; int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);} const int MAXN = 510; const int MAXM = MAXN * MAXN * 2; const int INF = 0x3f3f3f3f; struct Edge { int u,v,next; int w; }edge[MAXM]; int head[MAXN],tot; void init() { tot = 0; memset(head,-1,sizeof(head)); } void add_edge(int u,int v,int w) { edge[tot].u = u ; edge[tot].v = v; edge[tot].w = w; edge[tot].next = head[u]; head[u] = tot++; } bool used[MAXN]; int linker[MAXN]; int NX,NY,N; bool dfs(int u) { for (int i = head[u] ; i != -1 ; i = edge[i].next) { int v = edge[i].v; if (!used[v]) { used[v] = true; if(linker[v] == -1 || dfs(linker[v])) { linker[v] = u; return true; } } } return false; } struct node { int height; int music; int sport; }man[MAXN],woman[MAXN]; map<string,int>act,art; char str[MAXN],res[MAXN]; void build() { init(); for (int i = 0 ; i < NX; i++) { for (int j = 0 ; j < NY ; j++) { if (abs(man[i].height - woman[j].height) <= 40 && man[i].music == woman[j].music && man[i].sport != woman[j].sport) add_edge(i,j,9797); } } } int main() { int T; scanf("%d",&T); while (T--) { act.clear(); art.clear(); scanf("%d",&N); NX = NY = 0; int cas = 1,leap = 1; for (int i = 0 ; i < N ; i++) { int height; char tmp[5]; scanf("%d%s%s",&height,tmp,str); if (!art[str]) art[str] = cas++; scanf("%s",res); if (!act[res]) act[res] = leap++; if (tmp[0] == 'F') { man[NX].height = height; man[NX].music = art[str]; man[NX++].sport = act[res]; } else { woman[NY].height = height; woman[NY].music = art[str]; woman[NY++].sport = act[res]; } } build(); int ret = 0; memset(used,false,sizeof(used)); memset(linker,-1,sizeof(linker)); for (int i = 0 ; i < NX ; i++) { memset(used,false,sizeof(used)); if (dfs(i)) ret++; } printf("%d\n",N - ret); } return 0; }
UVALIVE 3126 Taxi Cab Scheme
#include <map> #include <set> #include <list> #include <cmath> #include <ctime> #include <deque> #include <stack> #include <queue> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <climits> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #define LL long long #define PI 3.1415926535897932626 using namespace std; int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);} const int MAXN = 510; const int MAXM = MAXN * MAXN * 2; const int INF = 0x3f3f3f3f; struct Edge { int u,v,next; int w; }edge[MAXM]; int head[MAXN],tot; void init() { tot = 0 ; memset(head,-1,sizeof(head)); } void add_edge(int u,int v,int w) { edge[tot].u = u; edge[tot].v = v; edge[tot].w = w; edge[tot].next = head[u]; head[u] = tot++; } int NX,NY,N; int linker[MAXN]; bool used[MAXN]; bool dfs(int u) { for (int i = head[u]; i != -1 ; i = edge[i].next) { int v = edge[i].v; if (!used[v]) { used[v] = true; if (linker[v] == -1 || dfs(linker[v])) { linker[v] = u; return true; } } } return false; } struct node { int stx,sty; int edx,edy; int tim; }src[MAXN]; void read() { scanf("%d",&N); for (int i = 0 ; i < N ; i++) { int tmp1,tmp2; scanf("%d:%d%d%d%d%d",&tmp1,&tmp2,&src[i].stx,&src[i].sty,&src[i].edx,&src[i].edy); src[i].tim = tmp1 * 60 + tmp2; } init(); for (int i = 0 ; i < N ; i++) { for (int j = 0 ; j < N ; j++) { if (i == j) continue; int dis = abs(src[i].edx - src[j].stx) + abs(src[i].edy - src[j].sty); if (src[i].tim + abs(src[i].edx - src[i].stx) + abs(src[i].edy - src[i].sty) + dis + 1 <= src[j].tim) add_edge(i,j,9797); } } } int main() { int T; scanf("%d",&T); while (T--) { read(); memset(linker,-1,sizeof(linker)); NX = NY = N; int ret = 0; for (int i = 0 ; i < NX ; i++) { memset(used,false,sizeof(used)); if (dfs(i)) ret++; } printf("%d\n",N - ret); } return 0; }
今年输的,明年全都要赢回来