题目:
http://poj.org/problem?id=1776
题意:
给出一个n*n的矩阵,若第i个任务做完之后可以做第j个任务,则矩阵的第i行第j列为1,否则为0。机器完成一项任务之后会自动转到下一个任务,否则机器会自动停止。
求出最少的启动次数,输出每次启动次数完成的任务个数和任务序列。
思路:
题目给出一个竞赛图(即任意两点之间有且仅有一条有向边的有向图),则竞赛图一定存在哈密顿路径。
题目转化为求一条哈密顿路径。
AC.
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 1005;
int n;
int g[maxn][maxn];
int next[maxn];
void solve()
{
memset(next, -1, sizeof(next));
int head = 1, t;
for(int i = 2; i <= n; ++i) {
bool flag = 0;
for(int j = head; ~j; j = next[j]) {
if(g[i][j]) {
if(j == head) head = i;
else next[t] = i;
next[i] = j;
flag = 1;
break;
}
else t = j;
}
if(!flag) next[t] = i;
}
printf("1\n%d\n", n);
for(int i = head; ~i; i = next[i]) {
printf("%d", i);
if(next[i] == -1) printf("\n");
else printf(" ");
}
}
char s[2500];
int main()
{
//freopen("in", "r", stdin);
while(~scanf("%d\n", &n)) {
for(int i = 1; i <= n; ++i) {
gets(s);
for(int j = 0; j < n; ++j) {
g[i][j+1] = s[j<<1] - '0';
}
}
// for(int i = 1;i <= n; ++i) {
// for(int j = 1; j <= n; ++j) {
// printf("%d ", g[i][j]);
// }
// puts(" ");
// }
solve();
}
return 0;
}