一.原题链接:http://poj.org/problem?id=1300
二.题目大意:判断是否能从一个给定的点出发,走到0点,其中所有的边只走一遍。
三.思路:无向图欧拉通路判定
1.G为连通图,并且G刚好有2个奇度顶点或无奇度顶点。
2.当刚好有2个奇度顶点,这2个顶点为起点和终点。
3.当无奇度顶点,必有欧拉回路。(图为欧拉图的充要条件)
所以题目要求要到达0,当没有奇度顶点,那么要回到0,起点只能为0。当有2个奇度顶点,说明没有回路,起点不能为0,并且起点和0都必须是奇度顶点。
四.代码:写得好挫,输入太坑。。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
using namespace std;
const int MAX_SIZE = 21,
INF = 0x3f3f3f3f;
int cnt[MAX_SIZE], start, nodeNum, edgeNum;
int myAtoi(char buffer[], int &point)
{
int i, res;
stack <int> sta;
for(i = 0; buffer[i] != ' ' && buffer[i]; i++){
sta.push(buffer[i] - '0');
}
res = 0;
if(!buffer[i])
i--;
point += i;
i = 0;
while(!sta.empty()){
res += sta.top()*pow(10.0, i);
i++;
sta.pop();
}
return res;
}
void addNode(char buffer[], int u)
{
int i, v;
for(i = 0; buffer[i]; i++){
v = myAtoi(buffer + i, i);
cnt[u]++, cnt[v]++; edgeNum++;
}
}
bool able()
{
int i, cntOdd = 0;
for(i = 0; i < nodeNum; i++)
if(cnt[i] & 1)
cntOdd++;
if(cntOdd == 0 && start == 0)
return true;
else if(cntOdd == 2 && (cnt[start]&1) &&
(cnt[0]&1) && start != 0)
return true;
return false;
}
int main()
{
//freopen("in.txt", "r", stdin);
int i, j;
char buffer[32], c;
while(1){
memset(cnt, 0, sizeof(cnt));
edgeNum = 0;
gets(buffer);
if('E' == buffer[0])
break;
for(i = 0; buffer[i] != ' '; i++);
i++;
start = myAtoi(buffer + i , i);
i++;
nodeNum = myAtoi(buffer + i, i);
for(i = 0; i < nodeNum; i++){
gets(buffer);
addNode(buffer, i);
}
if(able()){
cout<<"YES "<<edgeNum<<endl;
}
else{
cout<<"NO\n";
}
gets(buffer);
}
return 0;
}