链接:http://www.icpc.moe/onlinejudge/showProblem.do?problemCode=3332
本文链接:http://www.cnblogs.com/Ash-ly/p/5454611.html
题意:
给你一个N,代表含有N个点的竞赛图,接着的N * (N- 1) / 2行两个点u, v,代表存在有向边<u,v>,问是否能构造出来一个哈密顿通路.
思路:
竞赛图一定含有哈密顿通路,不一定含有哈密顿回路.则不可能出现不存在的情况,直接构造就可以,至于方法可看我的另外一篇文章:http://www.cnblogs.com/Ash-ly/p/5452580.html.
注意:
构造的时候从后往前寻找1或者0的时候一定是按照当前序列的顺序查找到,而不是按照点本身的顺序查找,在这里WA了几次.
代码:
1 #include <iostream> 2 #include <cmath> 3 #include <cstdio> 4 #include <cstring> 5 #include <cstdlib> 6 #include <algorithm> 7 #include <queue> 8 #include <stack> 9 #include <vector> 10 11 using namespace std; 12 typedef long long LL; 13 const int maxN = 200; 14 15 //The arv[] length is len, insert key befor arv[index] 16 inline void Insert(int arv[], int &len, int index, int key){ 17 if(index > len) index = len; 18 len++; 19 for(int i = len - 1; i >= 0; --i){ 20 if(i != index && i)arv[i] = arv[i - 1]; 21 else{arv[i] = key; return;} 22 } 23 } 24 25 void Hamilton(int ans[maxN + 7], int map[maxN + 7][maxN + 7], int n){ 26 int ansi = 1; 27 ans[ansi++] = 1; 28 for(int i = 2; i <= n; i++){ 29 if(map[i][ans[ansi - 1]] == 1) 30 ans[ansi++] = i; 31 else{ 32 int flag = 0; 33 for(int j = ansi - 2; j > 0; --j){//在当前序列中查找0/1 34 if(map[i][ans[j]] == 1){ 35 flag = 1; 36 Insert(ans, ansi, j + 1, i); 37 break; 38 } 39 } 40 if(!flag)Insert(ans, ansi, 1, i); 41 } 42 } 43 } 44 45 int main() 46 { 47 //freopen("input.txt", "r", stdin); 48 int t; 49 scanf("%d", &t); 50 while(t--){ 51 int N; 52 scanf("%d", &N); 53 int M = N * (N - 1) / 2; 54 int map[maxN + 7][maxN + 7] = {0}; 55 for(int i = 0; i < M; i++){ 56 int u, v; 57 scanf("%d%d", &u, &v); 58 if(u < v)map[v][u] = 1;//建图,map[v][u] = 1,代表存在边<u, v>,且 u < v. 59 } 60 int ans[maxN + 7] = {0}; 61 Hamilton(ans, map, N); 62 for(int i = 1; i <= N; i++) 63 printf(i == 1 ? "%d":" %d", ans[i]); 64 printf(" "); 65 } 66 return 0; 67 }
代码2:
1 #include <iostream> 2 #include <cmath> 3 #include <cstdio> 4 #include <cstring> 5 #include <cstdlib> 6 #include <algorithm> 7 #include <queue> 8 #include <stack> 9 #include <vector> 10 11 using namespace std; 12 typedef long long LL; 13 const int maxN = 1000; 14 15 inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';} 17 18 void Hamilton(int ans[maxN + 7], int map[maxN + 7][maxN + 7], int n){ 19 int nxt[maxN + 7];//用数组模拟链表 20 memset(nxt, -1, sizeof(nxt)); 21 int head = 1; 22 for(int i = 2; i <= n; i++){ 23 if(map[i][head]){ 24 nxt[i] = head; 25 head = i; 26 }else{ 27 int pre = head, pos = nxt[head]; 28 while(pos != -1 && !map[i][pos]){ 29 pre = pos; 30 pos = nxt[pre]; 31 } 32 nxt[pre] = i; 33 nxt[i] = pos; 34 } 35 } 36 int cnt = 0; 37 for(int i = head; i != -1; i = nxt[i]) 38 ans[++cnt] = i; 39 } 40 41 int main() 42 { 43 freopen("input.txt", "r", stdin); 44 int N; 45 while(~scanf("%d", &N)){ 46 int map[maxN + 7][maxN + 7] = {0}; 47 for(int i = 1; i <= N; i++){ 48 for(int j = 1; j <= N; j++){ 49 int u; 50 read(u); 51 map[i][j] = u; 52 } 53 } 54 printf("%d %d ", 1, N); 55 int ans[maxN + 7] = {0}; 56 Hamilton(ans, map, N); 57 for(int i = 1; i <= N; i++) 58 printf(i == 1 ? "%d":" %d", ans[i]); 59 printf(" "); 60 } 61 return 0; 62 }