HDOJ 2647 Reward 【逆拓撲排序+分層】
阿新 • • 發佈:2017-06-13
一個人 鏈式前向星 scanf target one string.h dream set targe
題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=2647
題意:每一個人的基礎工資是888。 因為一部分人要顯示自己水平比較高,要求發的工資要比其它人中的一個人多。問你能不能滿足他們的要求,假設能的話終於一共要發多少錢,假設不能就輸出-1.
策略:拓撲排序。
這道題有些難點:一:數據大,建二維數組肯定不行,要換其它的數據結構(vector, 或者是鏈式前向星(本題代碼用的是鏈式前向星)); 二:要逆拓撲排序(就是將++in[b]換成++in[a])。 三要分層次(依據上一個的錢數+1就可以)。
不懂什麽是鏈式前向星 移步:http://blog.csdn.net/acdreamers/article/details/16902023
代碼:
#include<stdio.h> #include<string.h> #include<queue> #define MAXN 10005 int head[MAXN*2]; struct EdgeNode{ int to; int next; }; EdgeNode edges[MAXN*2]; int in[MAXN], queue[MAXN], money[MAXN]; int n, ans; int toposort() { ans = 0; memset(money, 0, sizeof(money)); int i, j; int iq = 0; for(i = 1; i <= n; i ++){ if(!in[i]){ queue[iq++] = i; } } for( i = 0; i < iq; i ++){ int temp = queue[i]; ans += money[temp]; for(j = head[temp]; j != -1; j = edges[j].next){ if(!--in[edges[j].to]){ queue[iq++] = edges[j].to; money[edges[j].to] = money[temp]+1;//這裏是分層次。 } } } return iq == n; } int main() { int m, i, a, b; while(scanf("%d%d", &n, &m) == 2){ memset(head, -1, sizeof(head)); memset(in, 0, sizeof(in)); for(i = 0; i < m; i ++){ scanf("%d%d", &a, &b); in[a]++; edges[i].to = a; edges[i].next = head[b]; head[b] = i; } int sum = 888*n; int flag = toposort(); printf("%d\n", flag?sum+ans:-1); } return 0; }
題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=2647
HDOJ 2647 Reward 【逆拓撲排序+分層】