cdoj916-方老师的分身 III 【拓扑排序】

http://acm.uestc.edu.cn/#/problem/show/916

方老师的分身 III

Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)

Submit Status

一天的讲座结束后,方老师的分身们聚在了一起。在合并成一个方老师之前。这些分身要求方老师的真身发糖。这些分身要求方老师至少给他们发888个糖。这还不够,有的分身要求分比另外某个分身的糖多。问方老师最少分多少糖。

Input

有多组数据。

第一行2个整数N(1≤N≤10000),M(0≤M≤20000)表示分身数和要求数。

接下来m行,每行2个整数x,y。表示x要求分的比y更多糖果。

Output

一个整数,方老师最少要分多少糖。如过无法完成分糖输出−1。

Sample input and output

Sample Input Sample Output
2 1
1 2
2 2
1 2
2 1
1777
-1

题解:很容易想到拓扑排序。题目里设计环,用拓扑排序可以判断环的存在。另外需要注意,拓扑的方向。

代码:

 1 #include <fstream>
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstring>
 5
 6 using namespace std;
 7
 8 const int cnt=888;
 9 const int N=10005;
10 const int M=20005;
11 int n,m;
12 int u[M],v[M],head[N],la[M];
13 int du[N],cn[N];
14 bool b;
15
16 void topology();
17
18 int main()
19 {
20     //freopen("D:\\input.in","r",stdin);
21     //freopen("D:\\output.out","w",stdout);
22     while(~scanf("%d%d",&n,&m)){
23         memset(head,-1,sizeof(head));
24         memset(du,0,sizeof(du));
25         memset(cn,0,sizeof(cn));
26         for(int i=0;i<m;i++){
27             scanf("%d%d",&v[i],&u[i]);
28             la[i]=head[u[i]];
29             head[u[i]]=i;
30             du[v[i]]++;
31         }
32         b=true;
33         topology();
34         if(b){
35             int ans=cnt*n;
36             for(int i=1;i<=n;i++){
37                 ans+=cn[i];
38             }
39             printf("%d\n",ans);
40         }else{
41             puts("-1");
42         }
43     }
44     return 0;
45 }
46 void topology(){
47     int top=-1;
48     for(int i=1;i<=n;i++)
49         if(!du[i])  du[i]=top,top=i;
50     for(int i=0;i<n;i++){
51         if(top==-1){
52             b=false;
53             return;
54         }else{
55             int j=top;
56             top=du[top];
57             for(int k=head[j];k!=-1;k=la[k]){
58                 cn[v[k]]=max(cn[v[k]],cn[j]+1);
59                 if(!(--du[v[k]]))   du[v[k]]=top,top=v[k];
60             }
61         }
62     }
63 }
时间: 2025-01-05 00:32:42

cdoj916-方老师的分身 III 【拓扑排序】的相关文章

UESTC 916 方老师的分身III --拓扑排序

做法: 如果有a<b的关系,则连一条a->b的有向边,连好所有边后,找入度为0的点作为起点,将其赋为最小的价值888,然后其所有能到的端点,价值加1,加入队列,删去上一个点,然后循环往复,直到队列为空,即每个点都赋予了一个权值为止. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #in

uestc 方老师的分身 III 拓扑排序

没什么好说的.. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<string> 6 #include<queue> 7 #include<algorithm> 8 #include<map> 9 #include<iomanip> 10 #include<cl

UESTC_方老师的分身 II CDOJ 915

方老师的分身 II Time Limit: 10000/5000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status 方老师计算出了走路时间最长的那个分身所用的时间.于是有个特殊的分身(据说是方老师真身!)就不想如此古板的走最短路了!由于这个分身的特殊性,这个分身对于单向边可以当双向边走.但是这个特殊的分身想走最短路的同时,要求至少经过k条边. Input 有多组数据 第一行两个整数n,m(1≤n

UESTC 914 方老师的分身I Dijkstra

题意:求有向图的往返最短路的最长长度. 分析:求第一次到所有点的距离可以用一次Dijkstra求最短路求出来.考虑回来的路,想想就知道,从每个点回来的路即为将边的方向反转再求一次最短路后的结果. 所以此题为求两次最短路. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #define Mod 100

UESTC 917 方老师的分身IV --求欧拉路径

判断欧拉路径是否存在及求出字典序最小的欧拉路径问题(如果存在). 将字符串的第一个字母和最后一个字母间连边,将字母看成点,最多可能有26个点(a-z),如果有欧拉路径,还要判断是否有欧拉回路,如果有,则需要找一个字典序最小的点开始生成这条链,否则以起点开始生成链,起点即为出度比入度大1的点. 欧拉路径是否存在的判定: 1.全部点在一个联通块                               ----用并查集判联通块的数量2.所有点出度入度相等                      

UESTC 915 方老师的分身II --最短路变形

即求从起点到终点至少走K条路的最短路径. 用两个变量来维护一个点的dis,u和e,u为当前点的编号,e为已经走过多少条边,w[u][e]表示到当前点,走过e条边的最短路径长度,因为是至少K条边,所以大于K条边的当做K条边来处理就好了.求最短路的三个算法都可以做,我这里用的是SPFA,比较简洁. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #incl

uestc 方老师的分身IV

类似POJ1386,参考的大神的博客 首先明确思路: 是否为连通图(并查集解决) -> 是否存在欧拉路径  ->  是否存在欧拉回路   (是,则选取字典序最小的输出,否则直接输出可行解) 注意区分有向图和无线图存在欧拉路径或者欧拉回路的条件: 无向图: G为连通图,并且G仅有两个奇度节点或者无奇度节点 推论:1.当G是仅有两个奇度节点的连通图时,G的欧拉通路必以此两个结点为端点 2.当G时无奇度结点的连通图时,G必有欧拉回路 3.G为欧拉图(存在欧拉回路)的充分必要条件是G为无奇度节点的连通

uestc 方老师的分身 II

题意:求s到t走过边数大于k的最短路 思路:邻接表实现,用w[u][e]来维护(看的大牛博客),u表示当前点,e表示已经经过多少条边.感觉有点类似DP. 在边数大于k的处理上,发现还是使之等于k(K<=50),节省存储空间. spfa算法实现. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<string>

UESTC_方老师分身 I CDOJ 914

方老师分身 I Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status 方老师为了开更多讲座,于是他分身了!早上他都在某一个教室分身,然后各个分身分别赶去各个不同的n个教室(当然每个教室都要有且只有一个分身).晚上各个分身都赶回之前分身时的教室,合并成一个人(不需要同时回去).但是教室间的路十分崎岖,而且是单向的.当然即便只是方老师的分身,那也是相当厉害的,