• codevs 4093 EZ的间谍网络


    同样是tarjan此题细节超多。。。

    大体思路是tarjan缩点,然后只考虑入度为0的连通块,对能不能收买分别讨论即可。

    然后第一次忘了打时间戳。

    然后第二次忘了判同在一个强连通分量里的情况。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<stack>
    #include<cmath>
    #define maxn 1234567
    #define maxv 3005
    #define maxe 8005
    using namespace std;
    struct edge
    {
    int u,v,nxt;
    }e[maxe];
    int n,p,r,g[maxv],nume=0,person[maxv];
    int low[maxv],dfn[maxv],times=0,father[maxv];
    int cnt=0,minn[maxv];
    int inq[maxv],ans,regis[maxv],ccc=0,kkk[maxv];
    bool vis[maxv],ins[maxv];
    stack <int> s;
    void addedge(int u,int v)
    {
    e[++nume].u=u;
    e[nume].v=v;
    e[nume].nxt=g[u];
    g[u]=nume;
    }
    void tarjan(int u)
    {
    low[u]=dfn[u]=++times;
    vis[u]=true;
    s.push(u);
    ins[u]=true;
    for (int i=g[u];i;i=e[i].nxt)
    {
    int v=e[i].v;
    if (vis[v]==false)
    {
    tarjan(v);
    low[u]=min(low[u],low[v]);
    }
    else if (ins[v]==true)
    low[u]=min(low[u],dfn[v]);
    }
    if (low[u]==dfn[u])
    {
    int vtx,cc=0;
    cnt++;
    do
    {
    vtx=s.top();
    s.pop();
    father[vtx]=cnt;
    ins[vtx]=false;
    if (person[vtx]!=0) minn[cnt]=min(minn[cnt],person[vtx]);
    kkk[cnt]=min(kkk[cnt],vtx);
    }
    while (vtx!=u);
    }
    }
    int main()
    {
    memset(vis,false,sizeof(vis));
    memset(person,0,sizeof(person));
    memset(ins,false,sizeof(vis));
    memset(g,0,sizeof(g));
    memset(inq,0,sizeof(inq));
    scanf("%d%d",&n,&p);
    for (int i=1;i<=n;i++)
    {
    minn[i]=maxn;
    kkk[i]=maxn;
    }
    int x,y;
    for (int i=1;i<=p;i++)
    {
    scanf("%d%d",&x,&y);
    person[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++)
    father[i]=i;
    for (int i=1;i<=n;i++)
    if (vis[i]==false)
    tarjan(i);
    for (int i=1;i<=nume;i++)
    if (father[e[i].u]!=father[e[i].v])
    inq[father[e[i].v]]++;
    int sum=0,flag=0,ans=maxn;
    for (int i=1;i<=cnt;i++)
    {
    if ((minn[i]==maxn) && (inq[i]==0))
    {
    flag=1;
    ans=min(ans,kkk[i]);
    }
    else if ((minn[i]!=maxn) && (inq[i]==0)) sum=sum+minn[i];
    }
    if (flag==0)
    printf("YES %d ",sum);
    else
    printf("NO %d ",ans);
    return 0;
    }

  • 相关阅读:
    3月3日(6) Climbing Stairs
    testNG 预期异常、忽略测试、超时测试
    testNG 常用的注解
    testNG 下载安装
    selenium 执行js代码
    selenium 时间等待的方法
    selenium 文件上传
    selenium 键盘鼠标模拟
    selenium 窗口的切换
    selemiun 下拉菜单、复选框、弹框定位识别
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/5081166.html
Copyright © 2020-2023  润新知