老板要给很多员工发奖金, 但是部分员工有个虚伪心态, 认为自己的奖金必须比某些人高才心理平衡; 但是老板很人道, 想满足所有人的要求, 并且很吝啬,想画的钱最少
输入若干个关系
a b
a c
c b
意味着a 的工资必须比b的工资高 同时a 的工资比c高; c的工资比b高
当出现环的时候输出-1
思路: 反向建图, 然后top排序分层次; 第一次的工资为888(最低), 第二层的工资 + 1, 后面一样
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#pragma warning(disable: 4996)
using namespace std;
const int MaxV = 10003;
const int MaxE = 20003;
struct Graph
{
void init()
{
top = 0;
memset(head, -1, sizeof(head));
}
void addEdge(int u, int v)
{
next[top] = head[u];
head[u] = top;
num[top] = v;
top++;
}
int top;
int head[MaxV], num[MaxE], next[MaxE];
};
Graph g;
int in[MaxV];
int logicalTopSort(int vexNum)
{
int tmp[MaxV], indexx = 0;
memset(in, 0, sizeof(in));
for(int i = 1; i <= vexNum; i++)
{
for(int j = g.head[i]; j != -1; j = g.next[j])
{
int v = g.num[j];
in[v]++;
}
}
int cengci = 0;
int res = 0;
for(int i = 1; i <= vexNum; i++)
{
int s = 1;
bool flag = false;
for(int j = 1; j <= vexNum; j++)
{
if(in[j] == 0)
tmp[s++] = j;
if(in[j] != -1)
flag = true;
}
if(s == 1 && flag)
return -1;
res += ((s - 1) * (888 + cengci));
cengci++;
for(int j = 1; j < s; j++)
{
in[tmp[j]] = -1;
for(int k = g.head[tmp[j]]; k != -1; k = g.next[k])
{
in[g.num[k]]--;
}
}
}
return res;
}
int main()
{
//freopen("data_in.txt", "r", stdin);
int vexNum, edgeNum;
int u, v;
while(scanf("%d %d", &vexNum, &edgeNum) != EOF)
{
g.init();
for(int i = 0; i < edgeNum; i++)
{
scanf("%d %d", &u, &v);
g.addEdge(v, u);
}
int ans = logicalTopSort(vexNum);
printf("%d\n", ans);
}
return 0;
}
不知道为什么不会超时, 感觉这个题目必须得用队列优化为O(n + m); 否者为o(n * n); 优化的时候一定要注意什么时候入队, 否则容易多次入队, 还有就是要注意怎么判断不能排序成功的条件