令每一个员工都有一个自己的等级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 }
我还在坚持,我还未达到我所想,梦~~一直在