zoukankan      html  css  js  c++  java
  • (拓扑排序)HDU

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=2647


    题意:

    一场比赛,现在已经有了结果,主办方要给选手分配奖励,判断是否能够分配,如果不能就输出-1,不能的话就输出主办方最小需要准备的奖金总数。

    每个选手最低给888元。


    分析:

    拓扑排序入门题吧。。

    我选择邻接表。

    把边倒着连,就能从最小开始,然后在进行队列的时候,然后进行一次拓扑排序即可,这里不同的奖金额度只需要用一个结构体里存一个level属性就可以了,一开始为0,后面push的+1就行了。

    每次pop加888+level。

    注意的地方就是:这题需要输出-1,一开始我只判断了有双向边,其实还应该判断是否成环,只要加个变量记录点访问的个数就行了。


    代码:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cmath>
      5 #include<cstring>
      6 #include<set>
      7 #include<vector>
      8 #include<queue>
      9 #include<map>
     10 #include<list>
     11 #include<bitset>
     12 #include<string>
     13 #include<cctype>
     14 #include<cstdlib>
     15 #include<sstream>
     16 
     17 using namespace std;
     18 
     19 typedef long long ll;
     20 typedef unsigned long long ull;
     21 #define inf (0x3f3f3f3f)
     22 #define lnf (0x3f3f3f3f3f3f3f3f)
     23 #define eps (1e-8)
     24 int sgn(double a) {
     25     return a < -eps ? -1 : a < eps ? 0 : 1;
     26 }
     27 
     28 const int maxn=10010;
     29 struct Node {
     30     int p,le;
     31 };
     32 
     33 ll ans;
     34 int pn;
     35 int m,n;
     36 
     37 vector<int> edge[maxn];
     38 int indu[maxn];
     39 
     40 
     41 
     42 void toposort() {
     43     queue<Node> q;
     44 
     45     for(int i=1; i<=n; i++) {
     46         if(indu[i]==0) {
     47             q.push(Node{i,0});
     48             indu[i]--;
     49         }
     50     }
     51 
     52     while(!q.empty()) {
     53         Node s = q.front();
     54         pn--;
     55         q.pop();
     56         ans+=s.le+888;
     57         for(int i=0; i<edge[s.p].size(); i++) {
     58             indu[edge[s.p][i]]--;
     59             if(indu[edge[s.p][i]]==0) {
     60                 q.push(Node{edge[s.p][i],s.le+1});
     61             }
     62         }
     63     }
     64 }
     65 
     66 
     67 void solve() {
     68 
     69     while(~scanf("%d%d",&n,&m)) {
     70         pn=n;
     71         for(int i=1; i<=n; i++) {
     72             edge[i].clear();
     73         }
     74         memset(indu,0,sizeof(indu));
     75         ans=0;
     76         int u,v;
     77         bool flag=true;
     78         for(int i=0; i<m; i++) {
     79             scanf("%d%d",&v,&u);
     80             for(int j=0; j<edge[v].size()&&flag; j++) {
     81                 if(edge[v][j]==u) {
     82                     flag=false;
     83                 }
     84             }
     85             bool have=false;
     86             for(int j=0; j<edge[u].size()&&flag&&!have; j++) {
     87                 if(edge[u][j]==v) {
     88                     have=true;
     89                 }
     90             }
     91             if(!have) {
     92                 indu[v]++;
     93                 edge[u].push_back(v);
     94             }
     95         }
     96         if(flag) {
     97             toposort();
     98             if(pn==0) {
     99                 printf("%lld
    ",ans);
    100             } else {
    101                 puts("-1");
    102             }
    103 
    104         } else {
    105             puts("-1");
    106         }
    107     }
    108 }
    109 
    110 
    111 
    112 int main() {
    113 
    114 #ifndef ONLINE_JUDGE
    115     freopen("in.txt", "r", stdin);
    116     //freopen("out.txt", "w", stdout);
    117 #endif
    118     //iostream::sync_with_stdio(false);
    119     solve();
    120     return 0;
    121 }
  • 相关阅读:
    hdu 4002 Find the maximum
    hdu 2837 坑题。
    hdu 3123
    zoj Treasure Hunt IV
    hdu 2053 Switch Game 水题一枚,鉴定完毕
    poj 1430 Binary Stirling Numbers
    hdu 3037 Saving Beans
    hdu 3944 dp?
    南阳oj 求N!的二进制表示最低位的1的位置(从右向左数)。
    fzu 2171 防守阵地 II
  • 原文地址:https://www.cnblogs.com/tak-fate/p/5974813.html
Copyright © 2011-2022 走看看