1. 程式人生 > >HDU 2647 Reward

HDU 2647 Reward

題意:boss需要發工資,每個人的最低工資為888,在給定的條件下,求boss需要發的最少工資和。
m個條件:每次為uv,代表u的工資高於v的工資。若出現矛盾,則輸出-1

思路:幾乎為裸的拓撲排序,在節點入隊時記錄該節點在拓撲序中所並列排的名次。

程式碼:

#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <queue>
#include <iostream>

using namespace
std; const int N = 1e4 + 10; typedef pair<int, int> P; vector<int> g[N]; int in[N]; int n, m; long long topologysort() { long long sum = 0; long long salary = 888; int out = n; queue<P> q; for (int i = 1; i <= n; i++) { if (in[i] == 0) q.push(make_pair(i, 0)); } while
(!q.empty()) { P f = q.front(); q.pop(); out--; sum = sum + salary + f.second; for (int i = 0; i < g[f.first].size(); i++) { int v = g[f.first][i]; in[v]--; if (in[v] == 0) q.push(make_pair(v, f.second + 1)); } } if (out != 0) return -1; return
sum; } int main() { while (scanf("%d%d", &n, &m) != EOF) { for (int i = 0; i < N; i++) g[i].clear(); memset(in, 0, sizeof(in)); for (int i = 0; i < m; i++) { int u, v; scanf("%d%d", &u, &v); g[v].push_back(u); in[u]++; } long long res = topologysort(); printf("%I64d\n", res); } return 0; }