其他分享
首页 > 其他分享> > SWERC 2019-20 G - Swapping Places

SWERC 2019-20 G - Swapping Places

作者:互联网

题意:给定S种动物,L个朋友关系,规定相邻的朋友可以交换位置,求排成一行的n个动物通过交换可以获得的最小字典序列
分析:发现不是朋友的动物之间相对位置无法改变,构成拓扑序,对于那些可以改变的,在拓扑排序的时候放进优先队列求字典序最小就行了
如何建图:对于第i个动物,只需要知道S种动物在它之前出现的位置,如果同一种动物在它之前出现多次,只需要记录最后一次的位置(即保证相对位置不改变),然后判断是否为朋友,如不是建立一条有向边,入度+1
#include<bits/stdc++.h>
using namespace std;

#define fr first
#define se second
#define et0 exit(0);
#define rep(i, a, b) for(int i = (a); i <= (b); i ++)
#define rrep(i, a, b) for(int i = (a); i >= (b); i --)

typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef unsigned long long ULL;

const int INF = 0X3f3f3f3f, N = 200 + 10, M = 1e5 + 10, MOD = 1e9 + 7;
const double eps = 1e-7;

int S, L, n;

string a[N], b[M];

int st[N][N];
int pos[M], last[N];
string ans[M];

unordered_map<string, int> msi;

int idx, head[M];
int in[M];
struct EDGE {
	int to, next;
} eg[200 * M];

void add(int x, int y) {
	eg[++idx].to = y;
	eg[idx].next = head[x];
	head[x] = idx;
}

void topo() {
	priority_queue<PII, vector<PII>, greater<PII> > q;
	rep(i, 1, n)
	if (!in[i]) q.push({msi[b[i]], i});
	int cnt = 0;
	while (!q.empty()) {
		PII cur = q.top();
		ans[++cnt] = b[cur.se];
		q.pop();
		for (int i = head[cur.se]; ~i; i = eg[i].next) {
			int to = eg[i].to;
			in[to]--;
			if (!in[to]) q.push({msi[b[to]], to});
		}
	}
}

void work() {
	cin >> S >> L >> n;
	rep(i, 1, S) cin >> a[i];
	sort(a + 1, a + 1 + S);
	rep(i, 1, S) msi[a[i]] = i;
	rep(i, 1, L) {
		string x, y;
		cin >> x >> y;
		st[msi[x]][msi[y]] = st[msi[y]][msi[x]] = 1;
	}
	memset(head, -1, sizeof head);
	memset(last, -1, sizeof last);
	rep(i, 1, n) cin >> b[i];
	rep(i, 1, n) {
		rep(j, 1, S)
		if (last[j] == -1 || st[msi[b[i]]][j]) continue;
		else {
			add(last[j], i);
			in[i]++;
		}
		last[msi[b[i]]] = i;
	}
	topo();
	rep(i, 1, n) cout << ans[i] << " ";
	cout << endl;
}

signed main() {

	work();

	return 0;
}

标签:head,20,int,rep,2019,msi,last,SWERC,eg
来源: https://www.cnblogs.com/xhy666/p/16456174.html