GYM 101572I(有向图上最小环)

逗号空格是假的,全都直接连边就行。
提供一个迪杰n次的图上最小环板子。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <map>
using namespace std;

const int maxn = 505;
const int inf = 0x3f3f3f3f;
typedef pair<int, int> pii;
int n;
string s[maxn];
string t;
int cnt;
map<string, int> id;
vector<int> adj[maxn];
int dis[maxn], pre[maxn], Ans[maxn];
int ans = inf, final;
int vis[maxn];

int dij(int st) {
	memset(pre, 0, sizeof pre);
	memset(dis, 0x3f, sizeof dis);
	priority_queue<pii, vector<pii>, greater<pii> > Q;
	for (int i : adj[st]) {
		Q.push({1, i});
		dis[i] = 1;
		pre[i] = st;
	}
	while (!Q.empty()) {
		int d = Q.top().first, u = Q.top().second;
		Q.pop();
		if (d > dis[u])	continue;
		
		for (int i : adj[u]) {
			if (dis[i] > dis[u] + 1) {
				dis[i] = dis[u] + 1;
				pre[i] = u;
				if (i == st)	return dis[i];
				Q.push({dis[i], i});
			}
		}
	}
	return dis[st];
}

void print(int cur) {
	if (vis[cur])	return;
	vis[cur] = 1;
	print(Ans[cur]);
	cout << s[cur] << " ";
}

int main() {
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> s[i];
		id[s[i]] = i;
	}
	for (int i = 1; i <= n; i++) {
		cin >> t >> cnt;
		int u = id[t];
		for (int j = 0; j < cnt; j++) {
			cin >> t;
			getline(cin, t);
			t.erase(0, 1);
			string tmp = "";
			for (int aa = 0; aa < t.length(); aa++) {
				if (t[aa] != ',') {
					tmp += t[aa];
				} else {
					int v = id[tmp];
					adj[u].push_back(v);
					aa++;
					tmp = "";
				}
			}
			if (tmp != "") {
				int v = id[tmp];
				adj[u].push_back(v);
			}
		}
	}
	for (int i = 1; i <= n; i++) {
		int tmp = dij(i);
		if (ans > tmp) {
			ans = tmp;
			final = i;
			memcpy(Ans, pre, sizeof pre);
		}
	}
	if (ans == inf) {
		puts("SHIP IT");
	} else {
		print(final);
	}
}
posted @ 2019-05-24 14:37  AlphaWA  阅读(198)  评论(0编辑  收藏  举报