Hdu - 2647 - Reward

上题目

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\n",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\n");
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\n");
82         else
83         {
84             sum=0;
85             for(i=1;i<=n;i++) sum+=f[i];
86             sum+=n*888;
87             printf("%d\n",sum);
88         }
89     }
90     return 0;
91 }
View Code

 

 

转载于:https://www.cnblogs.com/sineatos/p/3192087.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值