#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int num=3010;
const int inf=0x3f3f3f3f;
/*------------------*/
struct node{
int u,v,next;
}e[num*3];
int head[num],cnt,cnt2;
int ip[num];
/*------------------*/
int dfn[num],low[num],ind,stack[num],t,cnt3,f[num],w[num],w2[num];
bool vis[num];
int person[num];
/*------------------*/
struct point{
int id,v,fa;//id编号,v,费用,fa,父节点;
}a[num];
/*------------------*/
/*------------------*/
int n,p,r,all;
void int_i(void)
{
all=0;
memset(w,inf,sizeof(w));
cnt=-1;
memset(head,-1,sizeof(head));
ind=0;
memset(vis,0,sizeof(vis));
memset(dfn,0,sizeof(dfn));
memset(low,-1,sizeof(low));
t=0;
memset(stack,0,sizeof(stack));
cnt3=0;
memset(w,inf,sizeof(w));
memset(w2,inf,sizeof(w2));
memset(person,inf,sizeof(person));
memset(ip,0,sizeof(ip));
all=0;
return ;
}
void addedge(int u,int v)
{
e[++cnt].u=u;
e[cnt].v=v;
e[cnt].next=head[u];
head[u]=cnt;//忘了写这句,居然过了六组样例&..&;改了两个多小时的bug!!!!
return ;
}
void addedge2(int u,int v)
{
e[++cnt].u=u;
e[cnt].v=v;
e[cnt].next=head[u];
e[cnt].flag=false;
ip[v]++;
head[u]=cnt;
return;
}
void tarjan(int u)
{
int v;
dfn[u]=low[u]=++ind;
stack[++t]=u;
vis[u]=true;
for(int i=head[u];i!=-1;i=e[i].next)
{
v=e[i].v;
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(vis[v])
{
low[u]=min(low[u],dfn[v]);
}
}
if(dfn[u]==low[u])
{
++cnt3;
do{
v=stack[t--];
vis[v]=false;
f[v]=cnt3;
w2[cnt3]=min(w2[cnt3],w[v]);
person[cnt3]=min(person[cnt3],v);
// printf("cnt3==%d,v==%d\n",cnt3,v);
}while(v!=u);
}
return ;
}
int main()
{
int x=0,y;
bool flag;
//while(scanf("%d",&n)!=EOF)
//{
int_i();
scanf("%d%d",&n,&p);
for(int i=1;i<=p;i++)
{
scanf("%d%d",&x,&y);
w[x]=y;
}
scanf("%d",&r);
for(int i=1;i<=r;i++)
{
scanf("%d%d",&x,&y);
addedge(x,y);
}
for(int i=1;i<=n;i++)
{
if(!dfn[i]){
tarjan(i);
}
}
cnt2=cnt;
memset(head,-1,sizeof(head));//二次使用head数组
cnt=-1;
for(int i=0;i<=cnt2;i++)
{
x=e[i].u;
y=e[i].v;
if(f[x]!=f[y])
{
// printf("fx==%d,fy==%d\n",f[x],f[y]);
addedge2(f[x],f[y]);
}
}
// for(int i=1;i<=cnt3;i++)
// printf("ip=%d\n",ip[i]);
flag=true;
for(int i=1;i<=cnt3;i++)
{
if(ip[i]==0)
{
// printf("ip==%d,w==%d,per==%d\n",i,w[i],person[i]);
if(w2[i]==inf){
x=i;
flag=false;
break;
}
else
{
all+=w2[i];
}
}
}
if(!flag){
printf("NO\n%d\n",person[x]);
}
else {
printf("YES\n%d\n",all);
}
//}
return 0;
}
/*
4
2
1 100
4 200
2
1 2
3 4
4
2
1 100
4 200
2
1 2
3 4
3
2
1 10
2 100
2
1 3
2 3
3
2
1 10
2 100
2
1 3
2 3
*/
P1262 间谍网络+Trajan 缩点(有向图)
最新推荐文章于 2020-07-12 23:28:51 发布