2 1 1 2 2 2 1 2 2 1
1777 -1
题意:老板要给n个员工发年终奖金,然后给出m个需求 (a,b),表示a的奖金要比b的多,然后呢,老板决定每个员工至少可以拿888元,现在老板总共至少需要发多少奖金。
如果满足不了就输出-1。
分析:拓扑排序问题。比第i个人奖金少的总人数有sum个,那么第i个人的奖金就是888+sum元。注意此题数据比较大,用邻接表存吧。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2647
代码清单:
(1) vector实现
#include<map>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cctype>
#include<string>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
const int maxv = 10000 +5;
int n,m;
int p,q;
bool judge;
int save[maxv];
int degree[maxv];
vector<int>graph[maxv];
void init(){
memset(degree,0,sizeof(degree));
for(int i=0;i<=n;i++) graph[i].clear();
}
int topSort(){
int cnt=0;
int sum=0;
int q=888;
while(cnt<n){
int flag=0;
for(int i=1;i<=n;i++){
if(degree[i]==0){
degree[i]=-1;
save[flag++]=i;
cnt++;
}
}
if(!flag) return -1;
sum+=q*flag; q++;
for(int i=0;i<flag;i++){
int u=save[i];
for(int j=0;j<graph[u].size();j++){
int v=graph[u][j];
degree[v]--;
}
}
}return sum;
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
init();
for(int i=0;i<m;i++){
scanf("%d%d",&p,&q);
judge=false;
for(int j=0;j<graph[q].size();j++){
if(graph[q][j]==p){
judge=true;
break;
}
}
if(!judge){
graph[q].push_back(p);
degree[p]++;
}
}printf("%d\n",topSort());
}return 0;
}
(2)静态邻接表(数组)
#include<map>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cctype>
#include<string>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
const int maxv = 10000 + 5;
const int maxn = 20000 + 5;
struct Edge{
int to,next;
}graph[maxn];
int n,m;
int p,q;
int index;
bool judge;
int save[maxv];
int head[maxn];
int degree[maxv];
void init(){
index=1;
memset(head,0,sizeof(head));
memset(degree,0,sizeof(degree));
}
void add(int u,int v){
graph[index].to=v;
graph[index].next=head[u];
head[u]=index++;
}
int topSort(){
int cnt=0;
int sum=0;
int q=888;
while(cnt<n){
int flag=0;
for(int i=1;i<=n;i++){
if(degree[i]==0){
degree[i]=-1;
save[flag++]=i;
cnt++;
}
}
if(!flag) return -1;
sum+=q*flag; q++;
for(int i=0;i<flag;i++){
int u=save[i];
for(int j=head[u];j!=0;j=graph[j].next){
int v=graph[j].to;
degree[v]--;
}
}
}return sum;
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
init();
for(int i=0;i<m;i++){
scanf("%d%d",&p,&q);
judge=false;
for(int j=head[q];j!=0;j=graph[j].next){
if(graph[j].to==p){
judge=true;
break;
}
}
if(!judge){
add(q,p);
degree[p]++;
}
}printf("%d\n",topSort());
}return 0;
}
原文:http://blog.csdn.net/jhgkjhg_ugtdk77/article/details/45566293