点击去杭电AC 一起拿奖金
先看题目:
RewardTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 15861 Accepted Submission(s): 5073 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.
Input One line with two integers n and m ,stands for the number of works and the number of demands .(n<=10000,m<=20000) 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 |
- 要过年了,老板大气,要发年终奖了,每人888+
- 然鹅年终奖也是有等级的,并不是所有的人能都拿到一样奖金,这就要给大家排个序,而排序的方法就是拓扑排序
- 刚开始还以为是个线性关系,后来发现并不是,存在那种某个等级上蹲着好几个人的那种情况。。。
但这题是个坑,他给你的关系是a>b,通常情况下拓扑排序都是按大于关系来建图,但是关于这道题谁也不知道最高的等级是多少,所以只能逆向思维,根据小于关系来反向建图
还有个坑就是这道题的数据 1e4+,开个二维数组还真就爆内存了。。。深受其害~_~
可以用vector(然鹅我并不会)就只能先用静态链表了,vector的写法我一定会补上来的 ヾ(◍°∇°◍)ノ゙
还有就是代码的问题,一不小心把 j 写成 i 了,调了半天没找到哪里的错。。。太卑微了 Orz
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int mm=50005;
int n,m;
int head[mm];
int cnt;
int ru[mm];
int ceng[mm];//记录每一层的数量
struct node{
int to;//pp[i].to表示 路径i->to
int next;
}pp[mm*2];
int add(int x,int y){
for(int i=head[x];i!=-1;i=pp[i].next)
if(pp[i].to==y)
return 0;//去重边
pp[cnt].to=y;
pp[cnt].next=head[x];
head[x]=cnt++;
return 1;
}
void topo(){
queue<int>q;
int sum=0;
int num=0;
for(int i=1;i<=n;i++){
if(ru[i]==0)
q.push(i);
}
while(!q.empty()){
int size=q.size();
ceng[sum++]=size;//每一层的数量
for(int i=0;i<size;i++){
int temp=q.front();
q.pop();
num++;//判断是否成环
for(int j=head[temp];j!=-1;j=pp[j].next){
ru[pp[j].to]--;
if(ru[pp[j].to]==0)
q.push(pp[j].to); //憨瓜,把 j写成 i了。。。
}
}
}
if(num==n){
int res=0;
for(int i=0;i<sum;i++)
res+=(888+i)*ceng[i];//每一层的钱
printf("%d\n",res);
}
else printf("-1\n");
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF){
cnt=0;
memset(ru,0,sizeof(ru));
memset(head,-1,sizeof(ru));
int x,y;
while(m--){
cin>>x>>y;
if(add(y,x)==1) //反向存图!!!
ru[x]++; //
}
topo();
}
return 0;
}