原题见洛谷。
分析
首先这是有向图,又是一个举报一团,自然联想到缩点。
于是先缩点,记录每个缩的点的入度,其中是否有可买的间谍以及最低价格多少。
然后对于入度为0的缩点一定要在里面买一个间谍,如果入度为0又没有可买的间谍,flag=1,但是不要急着退出,把所有的缩点检查一遍。每买通一个就做一遍dfs标记哪些缩点被掌握。
如果flag=0,输出花费。flag=1,扫一遍所有的点(不是缩点)如果这个点属于的分量既没有被掌握,又没有可买的间谍,输出这个点,退出。
#include<bits/stdc++.h>
using namespace std;
const int MAXN=3005;
const int MAXM=8005;
const int INF=1000000;
int N,M,np=0,last[MAXN],val[MAXN];
int np2=0,last2[MAXN],rd[MAXN],cd[MAXN],buy[MAXN],have[MAXN];
int dfs_clock=0,top=0,scc=0,size[MAXN],belong[MAXN],stk[MAXN],dfn[MAXN],low[MAXN];
struct edge{int to,pre;};
edge E[MAXM],E2[MAXM];
char c;
void scan(int &x)
{
for(c=getchar();c<'0'||c>'9';c=getchar());
for(x=0;c>='0'&&c<='9';c=getchar()) x=x*10+c-'0';
}
void addedge(int u,int v)
{
E[++np]=(edge){v,last[u]};
last[u]=np;
}
void addedge2(int u,int v)
{
E2[++np2]=(edge){v,last2[u]};
last2[u]=np2;
}
void tarjan(int i)
{
dfn[i]=low[i]=++dfs_clock;
stk[++top]=i;
for(int p=last[i];p;p=E[p].pre)
{
int j=E[p].to;
if(dfn[j])
{
if(!belong[j]) low[i]=min(low[i],dfn[j]);
continue;
}
tarjan(j);
low[i]=min(low[i],low[j]);
}
if(low[i]==dfn[i])
{
scc++;
while(1)
{
int x=stk[top--];
belong[x]=scc;
size[scc]++;
buy[scc]=min(buy[scc],val[x]);
if(x==i) break;
}
}
}
void dfs(int i)
{
if(have[i]) return;
have[i]=1;
for(int p=last2[i];p;p=E2[p].pre)
{
int j=E2[p].to;
dfs(j);
}
}
void suodian()
{
int i,p,u,v;
for(i=1;i<=N;i++)
{
u=belong[i];
for(p=last[i];p;p=E[p].pre)
{
v=belong[E[p].to];
if(u==v) continue;
addedge2(u,v);
cd[u]++; rd[v]++;
}
}
}
void solve_NO()
{
puts("NO");
for(int i=1;i<=N;i++)
{
if(!have[belong[i]]&&buy[belong[i]]==INF)
{
cout<<i;
return;
}
}
}
int main()
{
int i,u,v,w;
scan(N);scan(M);
fill(val+1,val+N+1,INF);
fill(buy+1,buy+N+1,INF);
for(i=1;i<=M;i++)
{
scan(u);
scan(val[u]);
}
scan(M);
for(i=1;i<=M;i++)
{
scan(u);scan(v);
addedge(u,v);
}
for(i=1;i<=N;i++) if(!dfn[i]) tarjan(i);
suodian();
int cost=0,flag=0;
for(i=1;i<=scc;i++)
{
if(rd[i]==0)
{
if(buy[i]==INF) flag=1;
else
{
cost+=buy[i];
dfs(i);
}
}
}
if(flag) solve_NO();
else puts("YES"),cout<<cost;
return 0;
}
版权声明:本文为WWWengine原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。