题目链接:点击打开链接
题意:
给定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; }
时间: 2024-10-05 08:13:19