思路:
一些数据可能同时存在两个机器中,要停用其中一些(最少一个),使得受影响的最小
可以想到有向图的强连通分量,选择强连通分量后,则没有会受影响的。还有就是不能选指向别的强连通分量的;
然后 Tarjan 缩点;
#include<iostream>
#include<algorithm>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<set>
#include<queue>
#include<list>
#include<stack>
#include<map>
#pragma comment(linker, "/STACK:102400000,102400000")
#define PI acos(-1.0)
#define in freopen("in.txt", "r", stdin)
#define out freopen("out.txt", "w", stdout)
#define kuaidian ios::sync_with_stdio(0);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e5 + 7, maxd = 1e6 + 7;
const int mod = 1e9 + 7;
const int INF = 0x7f7f7f7f;
int n, m, h;
int t[maxn];
vector<int> e[maxn];
int dfn[maxn], low[maxn], vis[maxn], tim = 1;
int cnt[maxn], id[maxn], scc = 0;
stack<int> ans;
bool ok[maxn];
void init() {
memset(dfn, 0, sizeof dfn);
memset(vis, 0, sizeof vis);
memset(cnt, 0, sizeof cnt);
memset(ok, 1, sizeof ok);
scanf("%d%d%d", &n, &m, &h);
for(int i = 1; i <= n; ++i) scanf("%d", &t[i]);
for(int i = 0; i < m; ++i) {
int u, v; scanf("%d %d", &u, &v);
if((t[u]+1)%h == t[v]) e[u].push_back(v);
if((t[v]+1)%h == t[u]) e[v].push_back(u);
}
}
void tar(int u) {
dfn[u] = low[u] = tim++;
ans.push(u);
for(auto v : e[u]) {
if(!dfn[v]) tar(v);
if(!vis[v]) low[u] = min(low[u], low[v]);
}
if(dfn[u] == low[u]) {
scc++;
while(1) {
int v = ans.top(); ans.pop(); //cout << v << " * ";
id[v] = scc;
cnt[scc]++;
if(u == v) break;
}
//cout << endl;
}
}
int main() {
init();
for(int i = 1; i <= n; ++i) {
if(!dfn[i]) tar(i);
}
for(int i = 1; i <= n; ++i) {
for(auto j : e[i]) {
if(id[i] == id[j]) continue;
else ok[id[i]] = 0;
}
}
int ans1 = INF, ans2 = 0;
for(int i = 1; i <= scc; ++i) {
if(ok[i] && cnt[i] < ans1) {
ans1 = cnt[i];
ans2 = i;
}
}
cout << cnt[ans2] << endl;
for(int i = 1; i <= n; ++i) {
if(id[i] == ans2) cout << i << " ";
}
return 0;
}