Ant Trip
根据图中顶点的度数来确定欧拉路和欧拉回路。
题目要求的是有多少笔画能画完,图不一定是完全连通的,可以利用这一点将图进行“分块”。
如果这个分块中所有顶点的度数均为偶数,可以形成一个欧拉回路,则能有一笔画搞定。
然后是寻找欧拉路,一条欧拉路需要一笔,由欧拉路的性质得。在图中的所有奇度数顶点都是欧拉路产生的。
每两个奇度数结点都会产生一条欧拉路。所以算出图中的所有奇度数结点的个数除2就是图中所有欧拉路所产生的笔画数
对于图中可能产生的孤立结点。题目中最后提示说道“没有一条路与某一结点相连接,小蚂蚁就会忘记这个结点”,所以说孤立结点不作考虑。
:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int M = 100000+5;
int vis[M], n, father[M], deg[M], m;
int find(int num)
{
if (num != father[num])
{
father[num] = find(father[num]);
}
return father[num];
}
void Union(int a, int b)
{
a = find(a);
b = find(b);
if (a != b)
{
father[a] = b;
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("1.txt", "r", stdin);
#endif
int i, j, a, b, ans, r;
while(~scanf("%d%d", &n, &m))
{
for (i = 0; i <= n; i++)
{
father[i] = i;
vis[i] = 0;
deg[i] = 0;
}
for(i = 0; i < m; i++)
{
scanf("%d%d", &a, &b);
deg[a]++;
deg[b]++;
Union(a, b);
}
ans = 0;
for(i = 1; i <= n; i++)
{
if (deg[i]%2)
{
r = find(i);
vis[r] = 1;
ans++;
}
}
ans /= 2;
for(i = 1; i <= n; i++)
{
if(deg[i] > 0)
{
r = find(i);
if (!vis[r] && i == r)
{
ans ++;
}
}
}
cout << ans << endl;
}
return 0;
}