题解:
判断二分图
款搜判断
然后计算最大匹配
最后除以2
因为每一条边被算了两次
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; const int N=205; int flag[N],a[N][N],x,y,match[N],f[N],n,m; int bfs() { memset(flag,-1,sizeof(flag)); for (int j=1;j<=n;j++) { if (flag[j]!=-1) continue; queue<int> q; flag[j]=1; q.push(j); while (!q.empty()) { int k=q.front(); q.pop(); for (int i=1;i<=n;i++) { if (a[k][i]&&flag[i]==flag[k])return 0; if (a[k][i]&&flag[i]==-1) { q.push(i); flag[i]=1-flag[k]; } } } } return 1; } int dfs(int x) { for (int i=1;i<=n;i++) if (a[x][i]&&!f[i]) { f[i]=1; if (!match[i]||dfs(match[i])) { match[i]=x; return 1; } } return 0; } int main() { while (~scanf("%d%d",&n,&m)) { memset(a,0,sizeof(a)); while (m--) { scanf("%d%d",&x,&y); a[x][y]=1; a[y][x]=1; } if (!bfs()) { puts("No"); continue; } int ans=0; memset(match,0,sizeof(match)); for (int i=1;i<=n;i++) { memset(f,0,sizeof f); ans+=dfs(i); } printf("%d ",ans/2); } return 0; }