【二分圖】ZJOI2007小Q的遊戲
阿新 • • 發佈:2017-05-17
格子 scan clas ecn 輸出 每次 他還 顏色 sed
對於某些關卡,小Q百思不得其解,以致他開始懷疑這些關卡是不是根本就是無解的!!於是小Q決定寫一個程序來判斷這些關卡是否有解。
【輸入文件】
輸入文件qmatrix.in第一行包含一個整數T,表示數據的組數。
接下來包含T組數據,每組數據第一行為一個整數N,表示方陣的大小;接下來N行為一個N*N的01矩陣(0表示白色,1表示黑色)。
【輸出文件】
輸出文件應包含T行。對於每一組數據,如果該關卡有解,輸出一行Yes;否則輸出一行No。
【樣例輸入】
2
2
0 0
0 1
3
0 0 1
0 1 0
1 0 0
【樣例輸出】
No
Yes
【數據規模】
對於20%的數據,N≤ 7
對於50%的數據,N≤ 50
660. [ZJOI2007] 小Q的矩陣遊戲
★☆ 輸入文件:qmatrix.in
輸出文件:qmatrix.out
簡單對比
時間限制:1 s
內存限制:128 MB
對於100%的數據,N≤ 200
【題解】
這道題乍一看不像能用匈牙利算法
但其實我們仔細觀察一下就能發現,我們可以把為1的點的橫坐標與縱坐標加n連起來
然後看它是否有最大匹配等於n
就能知道可否完成
代碼如下:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; structedge{ int to,next; }e[40005]; int T,n,x,ans,ecnt,head[205],point[405]; bool used[4005]; void add(int a,int b) { ecnt++; e[ecnt]=(edge){b+200,head[a]}; head[a]=ecnt; } bool find(int a) { for(int i=head[a];i;i=e[i].next) { if(!used[e[i].to]) { used[e[i].to]=1; if(!point[e[i].to]||find(point[e[i].to])) { point[e[i].to]=a; return true; } } } return false; } int main() { scanf("%d",&T); while(T) { memset(e,0,sizeof(e)); memset(head,0,sizeof(head)); memset(point,0,sizeof(point)); ecnt=0; T--; scanf("%d",&n); for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) { scanf("%d",&x); if(x)add(i,j); } ans=0; for(int i=1;i<=n;++i) { memset(used,0,sizeof(used)); if(find(i))ans++; } if(ans==n)printf("Yes\n"); else printf("No\n"); } }
【二分圖】ZJOI2007小Q的遊戲