问题
http://hihocoder.com/problemset/problem/1174?sid=782321
http://hihocoder.com/contest/hiho48/problem/1
代码
首先找出所有入度为0的节点加入队列
1,每次从队列中拿出一个入度为0的节点,删除这个节点和其边
2,将入度为0的点加入队列。
重复1,2 直到队列为空。
#include <bits/stdc++.h>
using namespace std;
enum{maxn = 100000+5};
vector<int> G[maxn];
int inNum[maxn];
int main()
{
int t;
scanf("%d", &t);
while(t--){
int n, m;
scanf("%d %d", &n, &m);
for(int i=1; i<=n; ++i)
G[i].clear();
memset(inNum, 0, sizeof(inNum));
for(int i=0; i<m; ++i)
{
int a, b;
scanf("%d %d", &a, &b);
G[a].push_back(b);
++inNum[b];
}
queue<int> q;
for(int i=1; i<=n; ++i)
{
if (inNum[i]==0)
q.push(i);
}
int delNum =0;
while(q.size())
{
++delNum;
int now =q.front();
q.pop();
for (int i=0; i<G[now].size(); ++i)
{
int b = G[now][i];
--inNum[b];
if (inNum[b]==0)
q.push(b);
}
}
printf("%s\n", delNum ==n ? "Correct": "Wrong");
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
enum{maxn = 100000+5, mod=142857};
vector<int> G[maxn];
int inNum[maxn];
int virNum[maxn];
int main()
{
int n, m, k;
scanf("%d %d %d", &n, &m, &k);
memset(virNum, 0, sizeof(virNum));
memset(inNum, 0, sizeof(inNum));
for(int i=0; i<k; ++i)
{
int a;
scanf("%d", &a);
virNum[a] = (virNum[a]+1)%mod;
}
for(int i=0; i<m; ++i)
{
int a, b;
scanf("%d %d", &a, &b);
G[a].push_back(b);
++inNum[b];
}
queue<int> q;
for (int i=1; i<=n; ++i)
{
if (!inNum[i])
q.push(i);
}
int ret =0;
while(q.size())
{
int now = q.front();
q.pop();
ret = (ret+virNum[now]) %mod;
for(int i=0; i<G[now].size(); ++i)
{
int b = G[now][i];
--inNum[b];
virNum[b] = (virNum[b] + virNum[now])%mod;
if (!inNum[b])
{
q.push(b);
}
}
}
printf("%d\n", ret);
return 0;
}
本文介绍了如何通过图的拓扑排序解决特定问题,利用队列处理入度为0的节点,逐步删除节点及其连接边,直至遍历整个图。同时展示了两段C++代码示例,分别用于检查图是否存在拓扑排序以及计算特定节点的重要性。
3256

被折叠的 条评论
为什么被折叠?



