bzoj1443: [JSOI2009]游戏Game
感觉自己匈牙利很扎实,居然没有wa过
先是码了个O(n^2m)的(这里的n,m是点数和边数),就是每枚举到一个最大匹配里面的点,就删这个点重跑一次最大匹配
后来发现其实直接让这个点所匹配的点去找另一个就行了。(好像跑的挺慢。。)
网上好像都是网络流?不会啊还是自己yy匈牙利
/*#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; const int dx[4]={-1,0,1,0}; const int dy[4]={0,1,0,-1}; struct node { int x,y,next; }a[41000];int len,last[11000]; void ins(int x,int y) { len++; a[len].x=x;a[len].y=y; a[len].next=last[x];last[x]=len; } int zx,zy,ys[110][110]; struct point { int x,y; }px[11000],py[11000]; //-------init--------------- int del,wi;bool xin[11000],yin[11000]; int match[11000]; int tim,chw[11000]; bool findmuniu(int x) { for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(wi==2&&del==y)continue; if(chw[y]!=tim) { chw[y]=tim; if(match[y]==0||findmuniu(match[y])==true) { if(del==0)yin[y]=true; match[y]=x; return true; } } } return false; } int gomatch() { tim=0; memset(match,0,sizeof(match)); memset(chw,0,sizeof(chw)); if(del==0) { memset(xin,false,sizeof(xin)); memset(yin,false,sizeof(yin)); } int ret=0; for(int i=1;i<=zx;i++) { if(wi==1&&i==del)continue; tim++; if(findmuniu(i)==true) { ret++; if(del==0)xin[i]=true; } } return ret; } //----------------match----------------- point as[11000];int aslen; bool cmp(point p1,point p2){return (p1.x==p2.x)?(p1.y<p2.y):(p1.x<p2.x);} char ss[110]; int main() { freopen("game.in","r",stdin); freopen("game.out","w",stdout); int n,m; scanf("%d%d",&n,&m); zx=0;zy=0;memset(ys,-1,sizeof(ys)); for(int i=1;i<=n;i++) { scanf("%s",ss+1); for(int j=1;j<=m;j++) if(ss[j]=='.') { if((i+j)%2==0)ys[i][j]=++zx,px[zx].x=i,px[zx].y=j; else ys[i][j]=++zy,py[zy].x=i,py[zy].y=j; } } len=0;memset(last,0,sizeof(last)); for(int i=1;i<=n;i++) for(int j=(i%2==1?1:2);j<=m;j+=2) if(ys[i][j]!=-1) for(int k=0;k<=3;k++) { int ti=i+dx[k],tj=j+dy[k]; if(ti>0&&ti<=n&&tj>0&&tj<=m&&ys[ti][tj]!=-1) ins(ys[i][j],ys[ti][tj]); } //--------composition--------- del=0;wi=0; int mmax=gomatch(); aslen=0; for(int i=1;i<=zx;i++) { if(xin[i]==false)as[++aslen]=px[i]; else { del=i;wi=1; if(mmax==gomatch())as[++aslen]=px[i]; } } for(int i=1;i<=zy;i++) { if(yin[i]==false)as[++aslen]=py[i]; else { del=i;wi=2; if(mmax==gomatch())as[++aslen]=py[i]; } } if(aslen==0)printf("LOSE\n"); else { printf("WIN\n"); sort(as+1,as+aslen+1,cmp); for(int i=1;i<=aslen;i++)printf("%d %d\n",as[i].x,as[i].y); } return 0; }*/ #include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; const int dx[4]={-1,0,1,0}; const int dy[4]={0,1,0,-1}; struct node { int x,y,next; }a[41000];int len,last[11000]; void ins(int x,int y) { len++; a[len].x=x;a[len].y=y; a[len].next=last[x];last[x]=len; } int z,tp,ys[110][110]; struct point { int x,y; }p[11000]; //-------init--------------- bool in[11000]; int match[11000]; int tim,chw[11000]; bool findmuniu(int x) { for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(chw[y]!=tim) { chw[y]=tim; if(match[y]==0||findmuniu(match[y])==true) { in[y]=true; match[y]=x; match[x]=y; return true; } } } return false; } int gomatch() { tim=0; memset(match,0,sizeof(match)); memset(chw,0,sizeof(chw)); memset(in,false,sizeof(in)); int ret=0; for(int i=1;i<=tp;i++) { tim++; if(findmuniu(i)==true){ret++;in[i]=true;} } return ret; } bool findanother(int x) { for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(chw[y]!=tim&&y!=match[x]) { chw[y]=tim; if(match[y]==0||findanother(match[y])==true) return true; } } return false; } //----------------match----------------- point as[11000];int aslen; bool cmp(point p1,point p2){return (p1.x==p2.x)?(p1.y<p2.y):(p1.x<p2.x);} char ss[110][110]; int main() { freopen("game.in","r",stdin); freopen("game.out","w",stdout); int n,m; scanf("%d%d",&n,&m); z=0;memset(ys,-1,sizeof(ys)); for(int i=1;i<=n;i++)scanf("%s",ss[i]+1); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(ss[i][j]=='.') if((i+j)%2==0)ys[i][j]=++z,p[z].x=i,p[z].y=j; tp=z; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(ss[i][j]=='.') if((i+j)%2==1)ys[i][j]=++z,p[z].x=i,p[z].y=j; len=0;memset(last,0,sizeof(last)); for(int i=1;i<=n;i++) for(int j=(i%2==1?1:2);j<=m;j+=2) if(ys[i][j]!=-1) for(int k=0;k<=3;k++) { int ti=i+dx[k],tj=j+dy[k]; if(ti>0&&ti<=n&&tj>0&&tj<=m&&ys[ti][tj]!=-1) ins(ys[i][j],ys[ti][tj]), ins(ys[ti][tj],ys[i][j]); } //--------composition--------- int mmax=gomatch(); aslen=0; for(int i=1;i<=z;i++) { if(in[i]==false)as[++aslen]=p[i]; else { tim++; if(findanother(match[i])==true)as[++aslen]=p[i]; } } if(aslen==0)printf("LOSE\n"); else { printf("WIN\n"); sort(as+1,as+aslen+1,cmp); for(int i=1;i<=aslen;i++)printf("%d %d\n",as[i].x,as[i].y); } return 0; }
pain and happy in the cruel world.