2 条题解
-
0
缩点为有向无环图(DAG),半连通子图是一条链(不可能有分支,否则不同分支的点相互之间无法相连)
#include <bits/stdc++.h> using namespace std; const int N = 1100; vector<int> G1[N], G2[N]; int tsp, cnt, low[N], dfn[N], scc[N]; stack<int> stk; bool instk[N]; void tarjan(int x) { dfn[x] = low[x] = ++tsp; stk.push(x); instk[x] = 1; for (int y : G1[x]) { if (dfn[y] == 0) { tarjan(y); low[x] = min(low[x], low[y]); } else if (instk[y]) { low[x] = min(low[x], dfn[y]); } } if (low[x] == dfn[x]) { cnt++; int z; for (z = -1; z != x; ) { z = stk.top(); stk.pop(); instk[z] = 0; scc[z] = cnt; } } } int main() { int T; scanf("%d", &T); while (T--) { // 处理多组测试数据 int n, m; scanf("%d%d", &n, &m); memset(G1, 0, sizeof(G1)); // 初始化邻接表 for (int i = 1, x, y; i <= m; i++) { scanf("%d%d", &x, &y); G1[x].push_back(y); // 构建原图邻接表G1 } tsp = cnt = 0; // 初始化时间戳和SCC计数 memset(dfn, 0, sizeof(dfn)); memset(low, 0, sizeof(low)); memset(instk, 0, sizeof(instk)); memset(scc, 0, sizeof(scc)); for (int i = 1; i <= n; i++) { // 对每个未访问节点执行Tarjan算法 if (dfn[i] == 0) tarjan(i); } map<pair<int, int>, bool> mp; // 避免DAG中重复边 vector<int> rd(cnt + 1); // 记录DAG各节点入度 memset(G2, 0, sizeof(G2)); // 初始化DAG邻接表G2 for (int i = 1; i <= n; i++) { for (int j : G1[i]) { // 将原图边转化为DAG边 int x = scc[i], y = scc[j]; if (x != y && !mp[{x, y}]) { // 不同SCC且无重复边 G2[x].push_back(y); rd[y]++; mp[{x, y}] = 1; } } } deque<int> q; // 用于拓扑排序 for (int i = 1; i <= cnt; i++) { if (rd[i] == 0) q.push_back(i); // 入度为0的节点入队 } bool flag = 1; // 标记是否为链 while (!q.empty()) { if (q.size() > 1) { // 若队列中超过一个节点,说明存在分支 flag = 0; break; } int x = q.front(); q.pop_front(); // 取出队首节点 for (int y : G2[x]) { // 处理x的邻接节点 if (--rd[y] == 0) q.push_back(y); // 入度为0时入队 } } printf("%s\n", flag ? "Yes" : "No"); // 输出结果 } return 0; } -
0
//缩点为有向无环图(DAG),半连通子图是一条链(不可能有分支,否则不同分支的点相互之间无法相连) #include<bits/stdc++.h> using namespace std; const int N=1100; vector<int>G1[N],G2[N]; int tsp,cnt,low[N],dfn[N],scc[N]; stack<int>stk;bool instk[N]; void tarjan(int x) { dfn[x]=low[x]=++tsp; stk.push(x);instk[x]=1; for(int y:G1[x]) { if(dfn[y]==0) { tarjan(y); low[x]=min(low[x],low[y]); } else if(instk[y])low[x]=min(low[x],dfn[y]); } if(low[x]==dfn[x]) { cnt++; for(int z=-1;z!=x;) { z=stk.top();stk.pop();instk[z]=0; scc[z]=cnt; } } } int main() { int T;scanf("%d",&T); while(T--) { int n,m;scanf("%d%d",&n,&m); memset(G1,0,sizeof(G1)); for(int i=1,x,y;i<=m;i++)scanf("%d%d",&x,&y),G1[x].push_back(y); tsp=cnt=0;memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low)); memset(instk,0,sizeof(instk));memset(scc,0,sizeof(scc)); for(int i=1;i<=n;i++)if(dfn[i]==0)tarjan(i); map<pair<int,int>,bool>mp; vector<int>rd(cnt+1); memset(G2,0,sizeof(G2)); for(int i=1;i<=n;i++)for(int j:G1[i]) { int x=scc[i],y=scc[j]; if(x!=y && !mp[{x,y}]) G2[x].push_back(y),rd[y]++,mp[{x,y}]=1; } deque<int>q; for(int i=1;i<=cnt;i++) { if(rd[i]==0) { q.push_back(i); } } bool flag=1; while(!q.empty()) { if(q.size()>1){flag=0;break;} int x=q.front();q.pop_front(); for(int y:G2[x]) { rd[y]--; if(rd[y]==0)q.push_back(y); } } if(flag) printf("Yes\n");else printf("No\n"); } return 0; }
- 1
信息
- ID
- 1490
- 时间
- 1000ms
- 内存
- 64MiB
- 难度
- 8
- 标签
- 递交数
- 270
- 已通过
- 39
- 上传者