• Hdu


    上题目

    Reward

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 2522    Accepted Submission(s): 745


    Problem Description
    Dandelion's uncle is a boss of a factory. As the spring festival is coming , he wants to distribute rewards to his workers. Now he has a trouble about how to distribute the rewards.
    The workers will compare their rewards ,and some one may have demands of the distributing of rewards ,just like a's reward should more than b's.Dandelion's unclue wants to fulfill all the demands, of course ,he wants to use the least money.Every work's reward will be at least 888 , because it's a lucky number.
     
    Input
    One line with two integers n and m ,stands for the number of works and the number of demands .(n<=10000,m<=20000)
    then m lines ,each line contains two integers a and b ,stands for a's reward should be more than b's.
     
    Output
    For every case ,print the least money dandelion 's uncle needs to distribute .If it's impossible to fulfill all the works' demands ,print -1.
     
    Sample Input
    2 1 1 2 2 2 1 2 2 1
     
    Sample Output
    1777 -1
     
     
       这一题我终于AC了,这么多天终于A题了,感动啊T_T,这一题之前没有过超时了,这一次重新做了一遍,终于A了。
       题意就是拓扑排序,然后求给不同的员工发的工资最少是多少。由于不同的员工之间有可能会有比较,如果A>B,就要A的工资要比B的多。之前第一次的做法是在得到拓扑排序以后从顶向叶子遍历,记录层数,结果超时了。
      这一次的做法是在拓扑排序的同时进行记录层数,如果在当前的结点已经有一个层数的话,那么就要判断是当前新的层数大还是原来的层数大,记录更大的那个层数,这样才可以符合题意。最后只要将所有结点的层数加起来(最下层的结点层数为0),就可以得到需要多增加加金额。
      用这种方法时,邻接表是用来记录当前点i比哪些点的工资要少,同时开一个数组保存某一点i比多少个点要大(即保存数目),也就是说这里有点像开了一个邻接表和一个逆邻接表,只是我各取了这两个表的一部分。
       这一题不知道会不会出现重边,我用map来记录已经记录了边。
       还有这一题要注意的地方是要留意我需要的是i还是node[i].to(前者是当前结点在静态链表里面的指针值,后者是 当前结点的编号(名称))。
     
     
    先把超时的代码贴上
     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <string.h>
     4 #include <queue>
     5 #define MAX 10000+2
     6 using namespace std;
     7 
     8 typedef struct node
     9 {
    10     int x0;
    11     struct node *next;
    12 }node;
    13 
    14 node s[MAX];
    15 
    16 int d[MAX],e[MAX];
    17 
    18 queue<int> p;
    19 
    20 bool deal(int n)
    21 {
    22     int i,count;
    23     node *f,*r;
    24     while(!p.empty()) p.pop();
    25     count=0;
    26     for(i=1;i<=n;i++) if(!e[i]) {p.push(i);}
    27     while(!p.empty())
    28     {
    29         i=p.front();
    30         count++;
    31         p.pop();
    32         f=s[i].next;
    33         while(f)
    34         {
    35             e[f->x0]--;
    36             if(!e[f->x0])
    37             {
    38                 p.push(f->x0);
    39                 d[f->x0]=d[f->x0]<(d[i]+1) ? (d[i]+1) : d[f->x0];
    40             }
    41             r=f;
    42             f=f->next;
    43             free(r);
    44         }
    45     }
    46     if(n==count) return 1;
    47     return 0;
    48 }
    49 
    50 void jadge(int n)
    51 {
    52     int i,ans;
    53     ans=0;
    54     for(i=1;i<=n;i++) ans+=d[i];
    55     printf("%d
    ",ans+888*n);
    56 }
    57 
    58 void insert(int x,int y)
    59 {
    60     node *f;
    61     f=&s[x];
    62     while(f->next)
    63     {
    64         if(f->x0==y) return ;
    65     }
    66     f->next=(node*)malloc(sizeof(node));
    67     f->next->next=NULL;
    68     f->next->x0=y;
    69     e[y]++;
    70 }
    71 
    72 int main()
    73 {
    74     int n,m,i,x,y;
    75     //freopen("data.txt","r",stdin);
    76     while(scanf("%d %d",&n,&m)!=EOF)
    77     {
    78         for(i=1;i<=n;i++) {s[i].x0=i;s[i].next=NULL;}
    79         memset(d,0,sizeof(d));
    80         memset(e,0,sizeof(e));
    81         for(i=0;i<m;i++)
    82         {
    83             scanf("%d %d",&y,&x);
    84             insert(x,y);
    85         }
    86         if(!deal(n)) printf("-1
    ");
    87         else jadge(n);
    88     }
    89     return 0;
    90 }
    2647

    上代码:

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <string.h>
     4 #include <queue>
     5 #include <map>
     6 #include <vector>
     7 #include <algorithm>
     8 #define MAX (10000+2)
     9 using namespace std;
    10 
    11 int head[MAX],tot,co[MAX],f[MAX];
    12 
    13 typedef struct
    14 {
    15     int to;
    16     int next;
    17 }Node;
    18 
    19 Node node[MAX<<1];
    20 
    21 map<pair<int,int>,int> M;
    22 queue<int> q;
    23 
    24 int topo(int n)
    25 {
    26     int i,u,count;
    27     while(!q.empty()) q.pop();
    28     memset(f,0,sizeof(f));
    29     count=0;
    30     for(i=1;i<=n;i++)
    31     {
    32         if(!co[i])
    33         {
    34             f[i]=0;
    35             q.push(i);
    36         }
    37     }
    38     while(!q.empty())
    39     {
    40         u=q.front();
    41         q.pop();
    42         count++;
    43         for(i=head[u];i!=-1;i=node[i].next)
    44         {
    45             co[node[i].to ]--;
    46             if(co[node[i].to]==0)
    47             {
    48                q.push(node[i].to);
    49                f[node[i].to]=f[u]+1 > f[node[i].to] ? f[u]+1 : f[node[i].to];
    50             }
    51         }
    52     }
    53     if(count<n) return 0;
    54     return 1;
    55 }
    56 
    57 int main()
    58 {
    59     int n,m,i,sum;
    60     pair<int,int> e;
    61     //freopen("data.txt","r",stdin);
    62     while(scanf("%d %d",&n,&m)!=EOF)
    63     {
    64         memset(head,-1,sizeof(head));
    65         memset(co,0,sizeof(co));
    66         memset(node,0,sizeof(node));
    67         M.clear();
    68         tot=0;
    69         for(i=0;i<m;i++)
    70         {
    71             scanf("%d %d",&e.second,&e.first);    //first ==>right   second ==>left
    72             if(M.count(e)<=0)
    73             {
    74                 M.insert(pair<pair<int,int>,int>(e,1));
    75                 node[tot].to=e.second;
    76                 node[tot].next=head[e.first];
    77                 head[e.first]=tot++;
    78                 co[e.second]++;
    79             }
    80         }
    81         if(!topo(n)) printf("-1
    ");
    82         else
    83         {
    84             sum=0;
    85             for(i=1;i<=n;i++) sum+=f[i];
    86             sum+=n*888;
    87             printf("%d
    ",sum);
    88         }
    89     }
    90     return 0;
    91 }
    View Code

  • 相关阅读:
    【BZOJ1495】[NOI2006]网络收费 暴力+DP
    【BZOJ2827】千山鸟飞绝 hash+堆+SBT
    【BZOJ2905】背单词 fail树+DFS序+线段树
    【BZOJ3120】Line 矩阵乘法
    【BZOJ1441】Min 拓展裴蜀定理
    【BZOJ3195】[Jxoi2012]奇怪的道路 状压DP
    【BZOJ3416】Poi2013 Take-out 栈
    【BZOJ4244】邮戳拉力赛 DP
    【BZOJ3717】[PA2014]Pakowanie 状压DP
    【BZOJ1217】[HNOI2003]消防局的设立 树形DP
  • 原文地址:https://www.cnblogs.com/sineatos/p/3192087.html
Copyright © 2020-2023  润新知