题目链接:http://codeforces.com/contest/949/problem/C
题意:一天有h小时,某公司有N个信息,每个信息给出一个时间,0-h-1, 现在有m个客户,每个客户有2个信息in1,in2,in1!=in2,问选择一个最小的信息集合,将这集合里的信息时间全部往后推一个小时,如果信息时间为h-1,则变成0。求这个最小集合,并且时间改变后,客户2个信息的时间t[in1[i]]!= t[in2[i]]。
题解:若当前客户信息1时间+1可以到达信息2时间,对信息1连一条到信息2的单向边,说明如果改1,2也要改,对M个客户做这个操作。然后缩点,要改变的集合肯定是某个缩过点,且出度为0的集合,统计下出度为0的集合,取size(S)最小的即可。
难点:题意过于复杂。
#include <bits/stdc++.h>
using namespace std;
using ll = long long ;
using ld = long double;
#define pb push_back
#define SZ(X) ((int)X.size())
#define mp make_pair
#define Fi first
#define Se second
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pli pair<ll,int>
#define pil pair<int,ll>
#define ALL(X) X.begin(),X.end()
#define RALL(X) X.rbegin(),X.rend()
#define rep(i,j,k) for(int i = j;i <= k;i ++)
#define per(i,j,k) for(int i = j;i >= k;i --)
#define mem(a,p) memset(a,p,sizeof(a))
const int N = 1E5 + 7;
vector<int>G[N];
int sta[N];
int instack[N];
int bcnt, belong[N];
int index, sz;
int dfn[N], low[N];
int in1[N],in2[N];
int t[N];
int out[N];
void tarjan(int u)
{
instack[u] = true;
dfn[u] = low[u] = ++index;
sta[++sz] = u;
for(auto v:G[u]) {
if(!dfn[v]) {
tarjan(v);
low[u] = min(low[u], low[v]);
} else if(instack[v]) {
low[u] = min(low[u], dfn[v]);
}
}
if(dfn[u] == low[u]) {
int v;
bcnt ++;
do {
v = sta[sz--];
belong[v] = bcnt;
instack[v] = false;
}while(u != v);
}
}
int S[N];
int main()
{
int n, m, h;
scanf("%d %d %d",&n, &m, &h);
rep(i,1,n) scanf("%d",&t[i]);
rep(i,1,m) scanf("%d %d",&in1[i],&in2[i]);
rep(i,1,m) if(t[in1[i]]>t[in2[i]]) swap(in1[i],in2[i]);
rep (i,1,m) {
if(t[in1[i]]+1 == t[in2[i]]) G[in1[i]].pb(in2[i]);
if((t[in2[i]]+1)%h == t[in1[i]]) G[in2[i]].pb(in1[i]);
}
rep(i,1,n) if(!dfn[i]) tarjan(i);
// printf("%d\n",bcnt);
// rep(i,1,n) printf("%d ",belong[i]);
rep (i, 1, n) {
for(auto u : G[i]) {
if(belong[u] != belong[i]) out[belong[i]] ++;
}
}
rep (i, 1, n) {
S[belong[i]] ++;
}
int res = 1<<29;
int p = -1;
rep (i, 1, n) {
if(out[belong[i]] == 0) {
if(p == -1) res = S[belong[i]], p = belong[i];
else {
if(S[belong[i]] < res) {
p = belong[i];
res = S[belong[i]];
}
}
}
}
printf("%d\n",res);
rep (i, 1, n) {
if(belong[i] == p) printf("%d ",i);
}
return 0;
}