首页 > 代码库 > 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 逆向拓扑排序