HDU2444(二分圖的最大匹配+染色法判斷二分圖)
阿新 • • 發佈:2018-11-10
n=200,邊要開到1e5才能過。。。。。。
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #define eps 1e-8 #define memset(a,v) memset(a,v,sizeof(a)) using namespace std; typedef long long int LL; const int MAXN(1000); const int MAXM(1e5); const int INF(0x7f7f7f7f); const int mod(1e9+7); struct node { int to,next; node() {} node(int to,int next):to(to),next(next){} }edge[MAXM+50]; int head[MAXM+50]; bool vis[MAXN+50]; int color[MAXN+50]; int match[MAXN+50]; int cnt; int n,m; void init() { cnt=0; memset(head,-1); memset(vis,false);memset(color,-1); memset(match,-1); } void add_edge(int u,int v) { edge[cnt]=node(v,head[u]); head[u]=cnt++; } bool BFS(int u) { queue<int>q; q.push(u); color[u]=0; while(!q.empty()) { int v=q.front(); q.pop(); for(int i=head[v]; ~i ;i=edge[i].next){ int to=edge[i].to; if(color[to]==-1){ q.push(to); color[to]=(!color[v]); } else if(color[to]==color[v]) return false; } } return true; } bool dfs(int u) { for(int i=head[u]; ~i ;i=edge[i].next) { int to=edge[i].to; if(!vis[to]) { vis[to]=true; if(match[to]==-1||dfs(match[to])==true) { match[to]=u; return true; } } } return false; } int solve() { int ans=0; for(int i=1;i<=n;i++) { memset(vis,false); if(dfs(i)==true) ans++; } return ans; } int main(){ while(~scanf("%d%d",&n,&m)) { init(); for(int i=1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); add_edge(u,v); add_edge(v,u); } int flag=0; for(int i=1;i<=n;i++) { if(color[i]==-1&&BFS(i)==false) { flag=1; break; } } if(flag) { cout<<"No"<<endl; continue; } int ans=solve(); cout<<ans/2<<endl; } }