一,最少顶点覆盖:
求最少多少个顶点能够覆盖二分图中的所有的边,最小顶点覆盖=最大匹配=>对于二分图,求出最大匹配后只可能有两种边,未匹配边和匹配边,那么如果未匹配边未被任何一个顶点覆盖,那么这条边完全可以加入最大匹配中,所以最大匹配必然能够覆盖所有的边,得证。
poj1325:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,n) for(int i=1;i<=n;i++) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0; char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)){ x=x*10+c-'0'; c=getchar(); } return x; } int v[105],f[105],h[105],n,m,k; struct edge{ int to,next; }; edge e[1005]; int dfs(int x){ for(int j=h[x];j;j=e[j].next){ int tmp=e[j].to; if(v[tmp]) continue; v[tmp]=1; if(f[tmp]<0||dfs(f[tmp])){ f[tmp]=x; return 1; } } return 0; } int main(){ while(n=read()){ m=read();k=read(); int cur=0; clr(f,-1);clr(h,0); rep(i,k){ int u=read(),o=read(),ee=read(); e[++cur].to=ee; e[cur].next=h[o]; h[o]=cur; } int ans=0; rep(i,n){ clr(v,0); if(dfs(i)) ans++; } printf("%d\n",ans); } return 0; }
二,最大独立集。其实就是求有多少个点之间可以互相到达,因为可以求不能够互相到达的边的最小覆盖点,然后用所有的点数减去最小覆盖点就好了,不难理解;套模板套的好兴奋2333
poj3692:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,n) for(int i=1;i<=n;i++) #define clr(x,c) memset(x,c,sizeof(x)) const int nmax=205; int f[nmax][nmax],v[nmax],l[nmax]; int n,m,k; int read(){ int x=0; char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)){ x=x*10+c-'0'; c=getchar(); } return x; } bool dfs(int u){ rep(i,m){ if(!f[u][i]){ int tmp=i; if(!v[tmp]){ v[tmp]=1; if(l[tmp]<0||dfs(l[tmp])){ l[tmp]=u; return true; } } } } return false; } int main(){ int cur=0; while((n=read())&&(m=read())&&(k=read())){ clr(f,0); rep(i,k){ int u=read(),o=read(); f[u][o]=1; } clr(l,-1); int ans=0; rep(i,n){ clr(v,0); if(dfs(i)) ans++; } printf("Case %d: %d\n",++cur,n+m-ans); } return 0; }
再水一题。。。
poj2239:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,n) for(int i=1;i<=n;i++) #define clr(x,c) memset(x,c,sizeof(x)) struct edge{ int to,next; }; edge e[30005]; int f[200],v[200],h[305],n,m,k; int read(){ int x=0; char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)){ x=x*10+c-'0'; c=getchar(); } return x; } bool dfs(int u){ for(int i=h[u];i;i=e[i].next){ int tmp=e[i].to; if(!v[tmp]){ v[tmp]=1; if(f[tmp]<0||dfs(f[tmp])){ f[tmp]=u; return true; } } } return false; } int main(){ while(scanf("%d",&n)==1){ int cur=0; clr(f,-1);clr(h,0); rep(j,n){ int tmp=read(); rep(i,tmp){ int u=read(),o=read(); o=(u-1)*12+o; e[++cur].to=o; e[cur].next=h[j]; h[j]=cur; } } int ans=0; rep(i,n){ clr(v,0); if(dfs(i)) ans++; } printf("%d\n",ans); } return 0; }