将每个节点分成两个点,点与点之间连接容量为1的边,那么这个问题就转换成为最小割的问题,,同时要注意对于那些直接相连接的边要将他们之间添加一条容量为无穷大的边,同时在利用最大流算法进行解决的时候一定要注意以下几点:第一,要注意考虑图的连通性的问题,如果图是不连通的,那么就直接输出结果为0;同时对于那些已经直接连通的边,因为容量已经设置为无穷大的边,那么就可以直接不考虑,具体实现如下:
#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<sstream>
#include<cstdio>
#include<deque>
#include<functional>
using namespace std;
const int Inf = 1 << 30;
class Edge{
public:
int from, to, cap, flow;
Edge(int fr, int t, int c, int fl) :from(fr), to(t), cap(c), flow(fl){}
};
class Solve{
public:
int n, m;
vector<Edge> edge;
vector<int> G[500];
int area[55][55];
void addEdge(int from,int to,int cap){
edge.push_back(Edge(from, to, cap, 0));
edge.push_back(Edge(to, from, 0, 0));
int m = edge.size();
G[from].push_back(m - 2);
G[to].push_back(m - 1);
}
void Init(){
edge.clear();
memset(area, 0, sizeof(area));
for (int i = 0; i < 500; i++) G[i].clear();
for (int i = 0; i < n; i++){
addEdge(i, i + n, 1);
addEdge(i + n, i, 1);
}
for (int i = 0; i < m; i++){
int a, b;
scanf(" (%d,%d)",&a,&b);
area[a][b] = area[b][a] = 1;
addEdge(a, b + n, Inf);
addEdge(b, a + n, Inf);
}
}
int MaxFlow(int start,int end){
int flow = 0;
bool mark = false;
for (int i = 0; i < edge.size(); i++) edge[i].flow = 0;
while (true){
int Flow[500];
memset(Flow, 0, sizeof(Flow));
Flow[start] = Inf;
int parent[500];
queue<int> q;
q.push(start);
while (!q.empty()){
int id = q.front();
q.pop();
for (int i = 0; i < G[id].size(); i++){
int ide = G[id][i];
int to = edge[ide].to;
if (!Flow[to] && edge[ide].cap>edge[ide].flow){
Flow[to] = min(Flow[id], edge[ide].cap - edge[ide].flow);
parent[to] = ide;
q.push(to);
}
}
if (Flow[end]) break;
}
if ((!Flow[end])&&(!mark)) return -1;
if((Flow[end])&&(!mark)) mark = true;
if (!Flow[end]) break;
flow += Flow[end];
for (int i = end; i != start; i = edge[parent[i]].from){
edge[parent[i]].flow += Flow[end];
edge[parent[i] ^ 1].flow -= Flow[end];
}
}
return flow;
}
int Deal(){
Init();
int ans=Inf;
for (int j = 1; j < n; j++){
if (!area[0][j]){
int ans2 = MaxFlow(0, j+n);
if (ans2 == -1){
ans = 0;
break;
}
ans = min(ans, ans2);
}
}
if (ans >= (n - 1)) return n;
else return ans;
}
};
int main(){
Solve a;
while (scanf("%d %d",&a.n,&a.m)!=EOF){
int res = a.Deal();
cout << res << endl;
}
return 0;
}