HDU 2255 奔小康賺大錢 POJ 2195 Going Home 最大權完美匹配 KM演算法
阿新 • • 發佈:2019-02-17
兩道KM演算法模板題 可以作為求最大完美匹配模板
一個是求最大權,一個求最小權 ,最小權可以將所有的邊權取相反數,求得最大權之後再取反。
HDU 2255程式碼:
/*--------------------- #headfile--------------------*/ #include <algorithm> #include <iostream> #include <sstream> #include <cstring> #include <cstdlib> #include <cassert> #include <cstdio> #include <vector> #include <cmath> #include <queue> #include <stack> #include <set> #include <map> /*----------------------#define----------------------*/ #define DRII(X,Y) int (X),(Y);scanf("%d%d",&(X),&(Y)) #define EXP 2.7182818284590452353602874713527 #define CASET int _;cin>>_;while(_--) #define RII(X, Y) scanf("%d%d",&(X),&(Y)) #define DRI(X) int (X);scanf("%d", &X) #define mem(a,b) memset(a,b,sizeof(a)) #define rep(i,n) for(int i=0;i<n;i++) #define ALL(X) (X).begin(),(X).end() #define INFL 0x3f3f3f3f3f3f3f3fLL #define RI(X) scanf("%d",&(X)) #define SZ(X) ((int)X.size()) #define PDI pair<double,int> #define rson o<<1|1,m+1,r #define PII pair<int,int> #define MAX 0x3f3f3f3f #define lson o<<1,l,m #define MP make_pair #define PB push_back #define SE second #define FI first typedef long long ll; template<class T>T MUL(T x,T y,T P){T F1=0;while(y){if(y&1){F1+=x;if(F1<0||F1>=P)F1-=P;}x<<=1;if(x<0||x>=P)x-=P;y>>=1;}return F1;} template<class T>T POW(T x,T y,T P){T F1=1;x%=P;while(y){if(y&1)F1=MUL(F1,x,P);x=MUL(x,x,P);y>>=1;}return F1;} template<class T>T gcd(T x,T y){if(y==0)return x;T z;while(z=x%y)x=y,y=z;return y;} #define DRIII(X,Y,Z) int (X),(Y),(Z);scanf("%d%d%d",&(X),&(Y),&(Z)) #define RIII(X,Y,Z) scanf("%d%d%d",&(X),&(Y),&(Z)) const double pi = acos(-1.0); const double eps = 1e-6; const ll mod = 1000000007ll; const int M = 100005; const int N = 315; using namespace std; /*----------------------Main-------------------------*/ int n, m; int mc[N], lx[N], ly[N], sk[N]; int vx[N], vy[N], w[N][N]; bool dfs(int x) { vx[x] = 1; for(int y = 1; y <= m; y++) { if(vy[y]) continue; int tmp = lx[x] + ly[y] - w[x][y]; if(tmp == 0) { vy[y] = 1; if(mc[y] == -1 || dfs(mc[y])) { mc[y] = x; return 1; } } else sk[y] = min(sk[y], tmp); } return 0; } int KM() { mem(mc, -1); mem(ly, 0); for(int i = 1; i <= n; i++) { lx[i] = -1e9; for(int j = 1; j <= m; j++) { lx[i] = max(lx[i], w[i][j]); } } for(int x = 1; x <= n; x++) { for(int i = 1; i <= m; i++) sk[i] = 1e9; while(1) { mem(vx, 0); mem(vy, 0); if(dfs(x)) break; int d = 1e9; for(int i = 1; i <= m; i++) if(!vy[i]) d = min(d, sk[i]); for(int i = 1; i <= n; i++) if(vx[i]) lx[i] -= d; for(int i = 1; i <= m; i++) { if(vy[i]) ly[i] += d; else sk[i] -= d; } } } int res = 0; for(int i = 1; i <= m; i++) { if(mc[i] != -1) res += w[mc[i]][i]; } return res; } void solve() { while(RI(n) != EOF) { m = n; for(int i = 1; i <= n; i++) { for(int j = 1; j <= m; j++) { RI(w[i][j]); } } printf("%d\n", KM()); } } int main() { // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); // CASET solve(); return 0; }
POJ 2195 程式碼:
/*--------------------- #headfile--------------------*/ #include <algorithm> #include <iostream> #include <sstream> #include <cstring> #include <cstdlib> #include <cassert> #include <cstdio> #include <vector> #include <cmath> #include <queue> #include <stack> #include <set> #include <map> /*----------------------#define----------------------*/ #define DRII(X,Y) int (X),(Y);scanf("%d%d",&(X),&(Y)) #define EXP 2.7182818284590452353602874713527 #define CASET int _;cin>>_;while(_--) #define RII(X, Y) scanf("%d%d",&(X),&(Y)) #define DRI(X) int (X);scanf("%d", &X) #define mem(a,b) memset(a,b,sizeof(a)) #define rep(i,n) for(int i=0;i<n;i++) #define ALL(X) (X).begin(),(X).end() #define INFL 0x3f3f3f3f3f3f3f3fLL #define RI(X) scanf("%d",&(X)) #define SZ(X) ((int)X.size()) #define PDI pair<double,int> #define rson o<<1|1,m+1,r #define PII pair<int,int> #define MAX 0x3f3f3f3f #define lson o<<1,l,m #define MP make_pair #define PB push_back #define SE second #define FI first typedef long long ll; template<class T>T MUL(T x,T y,T P){T F1=0;while(y){if(y&1){F1+=x;if(F1<0||F1>=P)F1-=P;}x<<=1;if(x<0||x>=P)x-=P;y>>=1;}return F1;} template<class T>T POW(T x,T y,T P){T F1=1;x%=P;while(y){if(y&1)F1=MUL(F1,x,P);x=MUL(x,x,P);y>>=1;}return F1;} template<class T>T gcd(T x,T y){if(y==0)return x;T z;while(z=x%y)x=y,y=z;return y;} #define DRIII(X,Y,Z) int (X),(Y),(Z);scanf("%d%d%d",&(X),&(Y),&(Z)) #define RIII(X,Y,Z) scanf("%d%d%d",&(X),&(Y),&(Z)) const double pi = acos(-1.0); const double eps = 1e-6; const ll mod = 1000000007ll; const int M = 100005; const int N = 115; using namespace std; /*----------------------Main-------------------------*/ int n, m; int mc[N], lx[N], ly[N], sk[N]; int vx[N], vy[N], w[N][N]; bool dfs(int x) { vx[x] = 1; for(int y = 1; y <= m; y++) { if(vy[y]) continue; int tmp = lx[x] + ly[y] - w[x][y]; if(tmp == 0) { vy[y] = 1; if(mc[y] == -1 || dfs(mc[y])) { mc[y] = x; return 1; } } else sk[y] = min(sk[y], tmp); } return 0; } int KM() { mem(mc, -1); mem(ly, 0); for(int i = 1; i <= n; i++) { lx[i] = -1e9; for(int j = 1; j <= m; j++) { lx[i] = max(lx[i], w[i][j]); } } for(int x = 1; x <= n; x++) { for(int i = 1; i <= m; i++) sk[i] = 1e9; while(1) { mem(vx, 0); mem(vy, 0); if(dfs(x)) break; int d = 1e9; for(int i = 1; i <= m; i++) if(!vy[i]) d = min(d, sk[i]); for(int i = 1; i <= n; i++) if(vx[i]) lx[i] -= d; for(int i = 1; i <= m; i++) { if(vy[i]) ly[i] += d; else sk[i] -= d; } } } int res = 0; for(int i = 1; i <= m; i++) { if(mc[i] != -1) res += w[mc[i]][i]; } return res; } char s[N][N]; int W, H; int cal(PII a, PII b) { return abs(a.FI - b.FI) + abs(a.SE - b.SE); } void solve() { while(RII(W, H)) { if(W == 0) break; for(int i = 0; i < W; i++) scanf("%s", s[i]); vector<PII> v1, v2; for(int i = 0; i < W; i++) { for(int j = 0; j < H; j++) { if(s[i][j] == 'H') v1.PB(MP(i, j)); if(s[i][j] == 'm') v2.PB(MP(i, j)); } } n = m = SZ(v1); for(int i = 0; i < n; i++) { for(int j = 0; j < m; j++) { w[i+1][j+1] = -cal(v1[i], v2[j]); } } printf("%d\n", -KM()); } } int main() { // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); // CASET solve(); return 0; }