标签:
题目大意:有一家公司,要发奖金了。因为勤劳度不同的缘故,所以奖金不能人人都相同,问如何发奖金才能使得人人都满意,且所花费的总金额达到最小
解题思路:我将攀比关系当成了有向边,并赋为-1,如果出现负环的话,表示怎样都不可能满足的
总金额达到最小,那只要比攀比的人多1就好了,这就是赋值为-1的缘故,接着SPFA,求出来,转为正值即可
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define N 10010
#define M 20010
#define INF 0x3f3f3f3f
int u[M], v[M], len[M], head[N], Next[M], in[N], d[N];
int cnt, n, m;
bool vis1[N], vis2[N];
void add_edgs(int s, int e, int l) {
u[cnt] = s;
v[cnt] = e;
len[cnt] = l;
Next[cnt] = head[s];
head[s] = cnt++;
}
void init() {
cnt = 0;
memset(vis1, 0, sizeof(vis1));
memset(head, -1, sizeof(head));
int x, y;
for (int i = 0; i < m; i++) {
scanf("%d%d", &x, &y);
add_edgs(y, x, -1);
vis1[x] = 1;
}
}
void SPFA() {
memset(vis2, 0, sizeof(vis2));
memset(d, 0x3f, sizeof(d));
memset(in, 0, sizeof(in));
queue<int> q;
for (int i = 1; i <= n; i++) {
if (!vis1[i]) {
d[i] = 0;
vis2[i] = 1;
q.push(i);
in[i]++;
}
}
bool flag = false;
while (!q.empty()) {
int t = q.front();
q.pop();
vis2[t] = 0;
for (int i = head[t]; i != -1; i = Next[i]) {
if (d[t] + len[i] < d[v[i]]) {
d[v[i]] = d[t] + len[i];
if(!vis2[v[i]]) {
vis2[v[i]] = 1;
q.push(v[i]);
in[v[i]]++;
if (in[v[i]] > n) {
flag = true;
break;
}
}
}
}
if (flag)
break;
}
if (flag) {
printf("-1\n");
return ;
}
int ans = n * 888;
for (int i = 1; i <= n; i++) {
if (d[i] == INF) {
printf("-1\n");
return ;
}
ans -= d[i];
}
printf("%d\n", ans);
}
int main() {
while (scanf("%d%d", &n, &m) != EOF ) {
init();
SPFA();
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/l123012013048/article/details/47177995