Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 14562 | Accepted: 3844 |
Description
Input
Output
Sample Input
1 3 3 1 2 2 3 3 1
Sample Output
Yes
Source
一开始想成只要判断强连通分量的个数是否是1就可以了,发现怎么也不对,再仔细读了题,发现对于x和y,只有有一方可以到另一方就可以了,所以做法是tarjan缩点然后找入度为0的点和出度为0的点是否有多个,如果入度为0的点超过1个或者出度为0的点超过1个就不行,
第一张图是入度为0的点有2个,显然上面两个点不满足题意,第二张图是出度为0的点有2个,显然上面的两个点不满足题意
#include<map> #include<set> #include<list> #include<stack> #include<queue> #include<vector> #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int N = 1010; const int M = 6100; const int inf = 0x3f3f3f3f; int DFN[N]; int low[N]; int block[N]; int Stack[N]; int in[N]; int out[N]; bool instack[N]; int head[N]; int cost[N]; int min_price[N]; int tot, sccnum, index, top, n, m; struct node { int next; int to; }edge[M]; void addedge(int from, int to) { edge[tot].to = to; edge[tot].next = head[from]; head[from] = tot++; } void tarjan(int u) { DFN[u] = low[u] = ++index; Stack[top++] = u; instack[u] = 1; for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if (DFN[v] == 0) { tarjan(v); if (low[u] > low[v]) { low[u] = low[v]; } } else if (instack[v]) { if (low[u] > DFN[v]) { low[u] = DFN[v]; } } } if (DFN[u] == low[u]) { sccnum++; do { top--; block[Stack[top]] = sccnum; instack[Stack[top]] = 0; }while ( top >=0 && Stack[top] != u); } } void solve() { memset( instack, 0, sizeof(instack) ); memset( DFN, 0, sizeof(DFN) ); memset( low, 0, sizeof(low) ); memset( in, 0, sizeof(in) ); memset( out, 0, sizeof(out) ); memset( min_price, inf, sizeof(min_price) ); sccnum = index = top = 0; for (int i = 1; i <= n; i++) { if (DFN[i] == 0) { tarjan(i); } } for (int i = 1; i <= n; i++) { for (int j = head[i]; j != -1; j = edge[j].next) { if (block[i] != block[edge[j].to]) { out[block[i]]++; in[block[edge[j].to]]++; } } } int zero_in = 0; int zero_out = 0; for (int i = 1; i <= sccnum; i++) { if (in[i] == 0) { zero_in++; } if (out[i] == 0) { zero_out++; } } if(zero_in >= 2 || zero_out >= 2) { printf("No\n"); } else { printf("Yes\n"); } } int main() { int t; scanf("%d", &t); while(t--) { scanf("%d%d", &n, &m); memset( head, -1, sizeof(head) ); tot = 0; int u, v; for (int i = 0; i < m; i++) { scanf("%d%d", &u, &v); addedge(u, v); } solve(); } return 0; }
#include<map> #include<set> #include<list> #include<stack> #include<queue> #include<vector> #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int N = 1010; const int M = 6100; const int inf = 0x3f3f3f3f; int DFN[N]; int low[N]; int block[N]; int Stack[N]; int in[N]; int out[N]; bool instack[N]; int head[N]; int cost[N]; int min_price[N]; int tot, sccnum, index, top, n, m; struct node { int next; int to; }edge[M]; void addedge(int from, int to) { edge[tot].to = to; edge[tot].next = head[from]; head[from] = tot++; } void tarjan(int u) { DFN[u] = low[u] = ++index; Stack[top++] = u; instack[u] = 1; for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if (DFN[v] == 0) { tarjan(v); if (low[u] > low[v]) { low[u] = low[v]; } } else if (instack[v]) { if (low[u] > DFN[v]) { low[u] = DFN[v]; } } } if (DFN[u] == low[u]) { sccnum++; do { top--; block[Stack[top]] = sccnum; instack[Stack[top]] = 0; }while ( top >=0 && Stack[top] != u); } } void solve() { memset( instack, 0, sizeof(instack) ); memset( DFN, 0, sizeof(DFN) ); memset( low, 0, sizeof(low) ); memset( in, 0, sizeof(in) ); memset( out, 0, sizeof(out) ); memset( min_price, inf, sizeof(min_price) ); sccnum = index = top = 0; for (int i = 1; i <= n; i++) { if (DFN[i] == 0) { tarjan(i); } } for (int i = 1; i <= n; i++) { for (int j = head[i]; j != -1; j = edge[j].next) { if (block[i] != block[edge[j].to]) { out[block[i]]++; in[block[edge[j].to]]++; } } } int zero_in = 0; int zero_out = 0; for (int i = 1; i <= sccnum; i++) { if (in[i] == 0) { zero_in++; } if (out[i] == 0) { zero_out++; } } if(zero_in >= 2 || zero_out >= 2) { printf("No\n"); } else { printf("Yes\n"); } } int main() { int t; scanf("%d", &t); while(t--) { scanf("%d%d", &n, &m); memset( head, -1, sizeof(head) ); tot = 0; int u, v; for (int i = 0; i < m; i++) { scanf("%d%d", &u, &v); addedge(u, v); } solve(); } return 0; }