poj 3687 反向拓扑寻求字典序最小解

版权声明:那个,最起码帮我加点人气吧,署个名总行吧 https://blog.csdn.net/qq_41670466/article/details/83096401

看题意可得,这道题很明显是反向拓扑排序求解的问题,只不过反向拓扑排序求的是标签的顺序,之后还有把每个标签所对应的质量联系起来就好。

代码:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<set>
#include<stack>

using namespace std;

const int maxn = 210;
const int maxm = 4e4 + 10;
typedef pair<int, int>pii;
struct Edge
{
		int from, to, next;
}edge[maxm];
int in[maxn];
int head[maxn];
int n, m;
int cnt = 0;

void addedge(int u, int v)
{
		Edge E = { u,v,head[u] };
		edge[cnt] = E;
		head[u] = cnt++;
}

void ini()
{
		memset(in, 0, sizeof(in));
		memset(head, -1, sizeof(head));
		cnt = 0;
}

void toopu()
{
		int num[maxn];
		priority_queue <int>que;
		stack<int>iron;
		for (int i = 1; i <= n; i++)
				if (in[i] == 0)
						que.push(i);
		while (!que.empty())
		{
				int t = que.top();
				que.pop();
				iron.push(t);
				for (int i = head[t]; i != -1; i = edge[i].next)
				{
						int p = edge[i].to;
						if (--in[p] == 0)
								que.push(p);
				}
		}
		if (iron.size() != n)
		{
				printf("-1\n");
				while (!iron.empty())
						iron.pop();
				return;
		}
		int pos = 1;
		while (!iron.empty())
		{
				int t = iron.top();
				num[t] = pos++;
				iron.pop();
		}
		for (int i = 1; i <= n; i++)
		{
				if (i == 1)
				{
						printf("%d", num[i]);
				}
				else
						printf(" %d", num[i]);
		}
		printf("\n");
}

int main()
{
		int t;
		scanf("%d", &t);
		while (t--)
		{
				set<pii>s;
				//printf("\n");
				scanf("%d %d", &n, &m);
				ini();
				for (int i = 0; i < m; i++)
				{
						int a, b;
						scanf("%d %d", &a, &b);
						pii p = make_pair(a, b);
						if (s.count(p) == 0)
						{
								s.insert(p);
								addedge(b, a);
								in[a]++;
						}
				}
				toopu();
		}
		//system("pause");
		return 0;
}

明天刷hdoj5638 然后后天刷poj2672拓扑这一章就可以翻篇了,然后就是做四五道线段树的题,然后就学习新的知识,比如博弈论,树的一些算法。

猜你喜欢

转载自blog.csdn.net/qq_41670466/article/details/83096401