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.
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.
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 }
上代码:
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 }