一.原题链接: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; }