POJ1325机器重启次数——二分图匈牙利算法模板
题目:http://poj.org/problem?id=1325
求最小点覆盖。输出最大匹配数就行,结果略复杂地弄了。
注意由题可知 可以直接把与0有关的边删掉。不过亲测不删0而计数时不计0就会WA。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int n,m,k,pre[205],head[205],xnt,a,x,y,ans; bool vis[205]; struct Node{ int next,to; }edge[2005]; void add(int x,int y) { edge[++xnt].next=head[x]; edge[xnt].to=y; head[x]=xnt; } bool dfs(int u) { vis[u]=1; for(int i=head[u];i;i=edge[i].next) { int v=edge[i].to; if(vis[v])continue; vis[v]=1; if(!pre[v]||dfs(pre[v])) { pre[v]=u;pre[u]=v;return true; } } return false; } int main() { while(1) { scanf("%d",&n); if(!n)return 0; memset(pre,0,sizeof pre); memset(head,0,sizeof head); xnt=0;ans=0; scanf("%d%d",&m,&k); for(int i=1;i<=k;i++) { scanf("%d%d%d",&a,&x,&y); if(!x||!y)continue; add(x,y+100);add(y+100,x); } for(int i=1;i<n;i++) if(!pre[i]) { memset(vis,0,sizeof vis); vis[i]=1;dfs(i); } memset(vis,0,sizeof vis); for(int i=1;i<n;i++) if(!pre[i]) { vis[i]=1;dfs(i); } for(int i=1;i<n;i++) if(!vis[i])ans++; for(int i=101;i<m+100;i++) if(vis[i])ans++; printf("%d\n",ans); } }