首页 > 代码库 > HDU 2647 逆向拓扑排序
HDU 2647 逆向拓扑排序
令每一个员工都有一个自己的等级level[i] , 员工等级越高,那么工资越高,为了使发的钱尽可能少,所以每一级只增加一单位的钱
输入a b表示a等级高于b,那么我们反向添加边,令b—>a那么in[a]++,再进行拓扑排序,每次都让边的终点的level值大于起始点,那么要用max取较大值
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 6 using namespace std; 7 8 const int N = 10005; 9 int n , m , level[N] ;10 int first[N] , in[N] , k;11 12 struct Path{13 int y , next;14 }path[N<<2];15 16 void add_edge(int x, int y)17 {18 in[y]++;19 path[k].y=y , path[k].next = first[x];20 first[x] = k++;21 }22 23 bool DAG()24 {25 memset(level,0,sizeof(level));26 int cnt = 0;//统计能形成无环图的最多的点的个数27 queue<int> q;28 for(int i = 1; i<= n ; i++)29 if(in[i] == 0){30 q.push(i);31 level[i] = 0;32 }33 while(true){34 if(q.empty()) break;35 int u = q.front();36 q.pop();37 cnt++;38 for(int i = first[u] ; i!=-1 ; i=path[i].next){39 int v= path[i].y;40 in[v]--;41 level[v] = max(level[v] , level[u]+1);42 if(in[v] == 0)43 q.push(v);44 }45 }46 if(cnt<n) return false;47 return true;48 }49 50 int main()51 {52 // freopen("a.in","rb",stdin);53 int a,b;54 memset(level , 0x3f , sizeof(level));55 while(~scanf("%d%d",&n,&m)){56 memset(first , -1 , sizeof(first));57 memset(in , 0 , sizeof(in));58 k=0;59 60 for(int i=0 ; i<m ; i++){61 scanf("%d%d",&a,&b);62 add_edge(b , a);63 }64 65 if(DAG()){66 int ans = 0;67 for(int i = 1 ; i<=n ; i++)68 ans+=888+level[i];69 printf("%d\n",ans);70 }71 else puts("-1");72 }73 return 0;74 }
HDU 2647 逆向拓扑排序
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。