刘汝佳的代码感觉拖泥带水的啊!!!只有自己撸一个了!!!
此题先开始让互相不讨厌的骑士连边然后就是求点连通分量拉,在点联通分量上的点都是阔能在一个圆桌上的,不过要注意的是点联通分量必须是奇数的,题目要求。。烦~~
//如果有重边弄一个标价变量k时就好了k==0时continue k>=1时不continue;
//这个程序还不能处理只有一个点的连通块如果需要计数这种情况的话先初始化让每个点都成一个连通块最后没和其他点在一起的点就单独成一个
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<stack>;
using namespace std;
struct edgee
{
int to,from;
};
int n, m;
int map[1050][1050], first[1050], nextt[2000020];
int edgetot;
edgee edge[2000020];
int deep;
int dfn[1050], low[1050];
stack<edgee>stackk;
vector<int>bcc[1050];
int bccamount;
void addedge(int from, int to)
{
edge[edgetot].to = to;
edge[edgetot].from = from;
nextt[edgetot] = first[from];
first[from] = edgetot;
edgetot++;
edge[edgetot].to = from;
edge[edgetot].from = to;
nextt[edgetot] = first[to];
first[to] = edgetot;
edgetot++;
}
void dfs(int num,int fa)
{
dfn[num] = low[num] = deep++;
for (int i = first[num]; i != -1; i = nextt[i])
{
edgee e = edge[i]; int to = e.to;
if (dfn[to] == 0)
{
stackk.push(e);
dfs(to,num);
low[num] = min(low[num], low[to]);
if (low[to] >= dfn[num])
{
edgee ee = stackk.top();//注意用的是栈来收集的边不是队列或者其他什么的。。。还有搜集的是边不是点为什么。。因为一个点阔以在多个点联通分量
while (ee.from!=num&&ee.to!=to)
{
int too = ee.to;
stackk.pop();
bcc[bccamount].push_back(too);
ee = stackk.top();
}
if(low[to]==dfn[num])bcc[bccamount].push_back(num), bcc[bccamount].push_back(to);//注意这两组数据 1->2 2->3 3->4 4->2和 1->2 2->3 3->1 3->4 4->5 5->6 6->4都是无向边
stackk.pop(); //这样写就是为了区别这些情况,当然如果只有一个点确实不会进桶不过由于先开始初始化了的
bccamount++; //所以不存在拉拉
}
}
else
{
if (to != fa)
low[num] = min(low[num], dfn[to]);//由于是无向图所以是不会有横向边的。。。
}
}
}
int show[2000],color[2000],countt[2000];
bool searchh(int num, int kind)
{
color[num] = 3 - kind;
for (int i = first[num]; i != -1; i = nextt[i])
{
int to = edge[i].to; if (show[to] == 0)continue;
if (color[to] == color[num])return false;
if (color[to] != 0)continue;
int kk = searchh(to, color[num]); if (!kk)return false;
}
return true;
}
void getbitwo()
{
for (int i = 0; i < bccamount; i++)
{
for (int j = 0; j < bcc[i].size(); j++)
{
int to = bcc[i][j]; show[to] = 1; color[to] = 0;
}
bool isright = false;
if (!bcc[i].empty())
isright= searchh(bcc[i][0],1);
for (int j = 0; j < bcc[i].size(); j++)
{
int to = bcc[i][j]; show[to] = 0; color[to] = 0;
if (!isright)countt[to] = 1;
}
}
}
int main()
{
while (scanf("%d%d", &n, &m) && n&&m)
{
while (!stackk.empty())stackk.pop();
edgetot = 0; deep = 0; bccamount = 0;
for (int i = 1; i <= n; i++)
{
first[i] = -1; dfn[i] = low[i] = 0; bcc[i].clear(); countt[i] = 0;
for (int j = 1; j <= n; j++)
map[i][j] = 0;
}
for (int i = 0; i < m; i++)
{
int a, b;
scanf("%d%d", &a, &b);
map[a][b] = map[b][a] = 1;
}
for (int i = 1; i <= n; i++)
for (int j = i + 1; j <= n; j++)
{
if (!map[i][j])addedge(i, j);//由于调试的需要现在我先改一下以后改回来!!!!!
}
for (int i = 1; i <= n; i++)
{
if (dfn[i] == 0)
dfs(i, -1);
}
getbitwo();
int ans = n;
for (int i = 1; i <= n; i++)
if (countt[i])ans--;
printf("%d\n", ans);
}
return 0;
}