• [HDU] 2647 Reward(拓扑排序)


    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=2647

    拓扑排序问题,反向建图,则最后入度为0的点初始金钱为888,以后每次删边入度为0的点金钱比上次+1即可。若存在环,则不可能出现,输出-1。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<string.h>
     4 #include<algorithm>
     5 #include<math.h>
     6 #include<stdbool.h>
     7 #include<time.h>
     8 #include<stdlib.h>
     9 #include<set>
    10 #include<map>
    11 #include<stack>
    12 #include<queue>
    13 #include<vector>
    14 using namespace std;
    15 #define clr(x,y)    memset(x,y,sizeof(x))
    16 #define sqr(x)      ((x)*(x))
    17 #define rep(i,a,b)  for(int i=(a);i<=(b);i++)
    18 #define LL          long long
    19 #define INF         0x3f3f3f3f
    20 #define A           first
    21 #define B           second
    22 const int N=10000+131;
    23 const int M=888;
    24 int n,m,cnt,sum,num,d[N],head[N],path[N];
    25 
    26 struct node
    27 {
    28     int u,v;
    29     int next;
    30 } edge[2*N];
    31 
    32 void init()
    33 {
    34     clr(d,0);
    35     clr(head,-1);
    36     cnt=0;
    37     sum=0;
    38     num=-1;
    39 }
    40 
    41 void add(int u,int v)
    42 {
    43     edge[cnt].v=v;
    44     edge[cnt].next=head[u];
    45     head[u]=cnt++;
    46 }
    47 
    48 void solve()
    49 {
    50     int u,i,f,p,x,y,res;
    51     while(~scanf("%d%d",&n,&m)) {
    52             init();
    53             while(m--) {
    54                 scanf("%d%d",&x,&y);
    55                 add(y,x);
    56                 d[x]++;
    57             }
    58             
    59             for(int i=0;i<n;i++) {
    60                 num++;
    61                 f=0;p=0;res=0;
    62                 for(int j=1;j<=n;j++) {
    63                     if(!d[j]) {
    64                         u=j;
    65                         d[j]--;
    66                         sum+=M+num;
    67                         f=1;
    68                         path[res++]=j;
    69                     }
    70                     if(d[j]>0) p=1;
    71                 }
    72                 
    73                 if(!f && p){  //有入度大于0的点,但不存在入度为0的点。即存在环
    74                     sum=-1;
    75                     break;
    76                 }
    77                 
    78                 for(int k=0;k<res;k++) {
    79                     u=path[k];
    80                     for(int j=head[u];j!=-1;j=edge[j].next) {
    81                         d[edge[j].v]--;
    82                     }
    83                 }
    84             }
    85             printf("%d
    ",sum);
    86     }
    87 }
    88 int main()
    89 {
    90     solve();
    91     return 0;
    92 }
  • 相关阅读:
    iconv 文件编码转换
    source insight 中文注释为乱码解决
    c: c代码书写规范
    Ubuntu: 搭建tftp,nfs服务器
    Linux: 信息查看
    liteos时间管理(九)
    最大连续子数列和
    递归为什么那么慢?递归的改进算法
    liteos信号量(八)
    liteos互斥锁(七)
  • 原文地址:https://www.cnblogs.com/sxiszero/p/4362933.html
Copyright © 2020-2023  润新知