題解:
真相是被splay和動態樹虐跪了...刷寫水題調整下鬱悶得不行的心態.... 匈牙利演算法我早忘了..二分圖嘛~~不管是最大匹配還是最大匹配最小代價~什麼匈牙利啊~KM啊都可以閃..有網路流就夠了....話是什麼說..但是匈牙利演算法寫起來還是比最簡單的網路流的寫法方便...效率也更高吧~~回顧下感覺不錯~
本題..(x,y)配對~經典構圖..找出最大匹配後..枚舉去掉某個點.看是否最大匹配減少了...
Program:
#include<iostream>#include<stdio.h>#include<algorithm>#include<cmath>#include<stack>#include<queue>#define ll long long#define MAXN 105using namespace std;int n,m,line[MAXN*MAXN][2],match[MAXN];bool arc[MAXN][MAXN],used[MAXN];bool dfs(int x){ int i; for (i=1;i<=m;i++) if (arc[x][i] && !used[i]) { used[i]=true; if (!match[i] || dfs(match[i])) { match[i]=x; return true; } } return false; }int getmax(){ int sum=0; memset(match,0,sizeof(match)); for (int i=1;i<=n;i++) { memset(used,false,sizeof(used)); sum+=dfs(i); } return sum;}int main(){ int i,k,cases,ans1,ans2; cases=0; while (~scanf("%d%d%d",&n,&m,&k)) { memset(arc,false,sizeof(arc)); for (i=1;i<=k;i++) { int x,y; scanf("%d%d",&x,&y); arc[x][y]=true,line[i][0]=x,line[i][1]=y; } ans2=getmax(),ans1=0; for (i=1;i<=k;i++) { int x=line[i][0],y=line[i][1]; arc[x][y]=false; int temp=getmax(); arc[x][y]=true; if (temp<ans2) ans1++; } printf("Board %d have %d important blanks for %d chessmen.\n",++cases,ans1,ans2); } return 0;}