题目链接:点击打开链接
题意:
给定n个点的有向图:
下面n行,第一个数字表示点权,后面一个数字m表示有m条边。
起点是1.
对于每个点,输出2个值表示前驱点权1和该点点权2。
1、若有多条路径到达该点且前驱的点权存在>0则输出unknown,否则输出前驱的点权(就是若有多条路径且全为0输出0,否则若只有一条路径则输出前驱点权,否则输出unknown)
2、若1输出的是0,则输出该点点权,否则若该点点权>0输出该点点权,否则输出前驱点权。
==略繁琐
#include <cstdio>
#include <cstring>
#include <cstring>
#include <vector>
using namespace std;
template <class T>
inline bool rd(T &ret) {
char c; int sgn;
if (c = getchar(), c == EOF) return 0;
while (c != '-' && (c<'0' || c>'9')) c = getchar();
sgn = (c == '-') ? -1 : 1;
ret = (c == '-') ? 0 : (c - '0');
while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
ret *= sgn;
return 1;
}
template <class T>
inline void pt(T x) {
if (x <0) {
putchar('-');
x = -x;
}
if (x>9) pt(x / 10);
putchar(x % 10 + '0');
}
const int N = 100005;
vector<int> g[N];
int k[N], f[N][2], vis[N];
void dfs(int idx, int fa) {
if(vis[idx]) {
if(f[idx][0] != f[fa][1]) {
f[idx][0] = -1;
if(!k[idx]) {
f[idx][1] = -1;
for(int i = 0; i < (int)g[idx].size(); i ++) {
int u = g[idx][i];
dfs(u, idx);
}
}
}
return ;
}
vis[idx] = 1;
f[idx][0] = f[fa][1];
f[idx][1] = k[idx] ? k[idx] : f[idx][0];
for(int i = 0; i < (int)g[idx].size(); i ++) {
int u = g[idx][i];
dfs(u, idx);
}
}
int main() {
int n, m;
while (~scanf("%d", &n)) {
memset(vis, 0, sizeof vis);
// memset(f, 0, sizeof f);
for(int i = 1; i <= n; i ++) g[i].clear();
for(int i = 1; i <= n; i ++) {
rd(k[i]), rd(m);
for(int j = 0, x; j < m; j ++) {
rd(x);
g[i].push_back(x);
}
}
vis[1] = 1;
f[1][0] = 0;
f[1][1] = k[1];
for(int i = 0; i < (int)g[1].size(); i ++) {
int u = g[1][i];
dfs(u, 1);
}
for(int i = 1; i <= n; i ++) {
if(f[i][0] == -1) printf("unknown ");
else if(f[i][0] == 0) printf("sober ");
else {
pt(f[i][0]);
putchar(' ');
}
if(f[i][1] == -1) printf("unknown\n");
else if(f[i][1] == 0) printf("sober\n");
else {
pt(f[i][1]);
putchar('\n');
}
}
}
return 0;
}