学霸周选课
Time Limit: 1000 MS Memory Limit: 128 MB
Submit Status
众所周知周大爷
不仅编程了得,专业课成绩更是名列前茅,恰巧又到了选课的季节,神秘的zin
作为周大爷
的好朋(基)友,给了周大爷
一份课表,这个课 表和一般的课表有些不同,它是一个有向无环图,图中每个节点表示一门课程,如果课程A有一条通向课程B的有向边,那么意味着,如果选了课程A,就能选课程B ,对于没有前驱的课程可以直接选择。
周大爷
看了课表后,发现自己非常想学课程kk,但是周大爷
又不想花太多精力去学别的课程,现在请你帮助周大爷
计算为了选上课程kk最少一共要选多少门课程(kk包含在内)。
Input
一个正整数nn(1≤n≤2000001≤n≤200000),kk (1≤k≤n1≤k≤n) ,mm(1≤m≤min(1000000,n(n−1)2)1≤m≤min(1000000,n(n−1)2)) 表示图中有mm条边.接下来mm行,每一行输入两个整数aa,bb(1≤a,b≤n1≤a,b≤n)表示如果选了课程aa就能选择课程bb。
Output
周大爷最少要选多少门课程
Sample input and output
Sample Input | Sample Output |
---|---|
3 2 1 1 2 | 2 |
Hint
样例不是test1
Source
2018 UESTC ACM Training for Graph Theory
题解:就是求要学这门课程,至少学几们课;我门可以用度,没输入一个 u ,v 使ind[v]++;
然后利用vector存储u后面的v,每次出来一个v,该v的度减一,该v的cost加一(cost要始终保持为当前最小的),
AC代码为:
#include<bits/stdc++.h> using namespace std; const int maxn=2e5+10; int n,k,m,u,v,ind[maxn],cost[maxn]; vector<int> V[maxn]; void toposort() { queue<int> q; for(int i=1;i<=n;i++) if(!ind[i]) q.push(i),cost[i]=1; while(!q.empty()) { int st=q.front();q.pop(); for(int i=0;i<V[st].size();i++) { int num=V[st][i]; cost[num]=min(cost[num],cost[st]+1); ind[num]--; if(!ind[num]) q.push(num); } } } int main() { ios::sync_with_stdio(false); cin.tie(0); memset(ind,0,sizeof ind); memset(cost,0x3f3f3f3f,sizeof(cost)); cin>>n>>k>>m; for(int i=0;i<m;i++) { cin>>u>>v; ind[v]++; V[u].push_back(v); } toposort(); cout<<cost[k]<<endl; return 0; }