• POJ


    题意:

    给你n个点,和m条单向边,问你有多少点满足(G)={v∈V|∀w∈V:(v→w)⇒(w→v)}关系,并把这些点输出(要注意的是这个关系中是蕴含关系而不是(&&)关系)

    题解:

    单独一个强连通分量中的所有点是满足题目要求的
    但如果它连出去到了其他点那里,要么成为新的强连通分量,要么失去原有的符合题目要求的性质
    所以只需tarjan缩点求出所有强连通分量,再O(E)枚举所有边,是否会成为连接一个分量与另一个分量的边——即一条出度——即可
    如果一个分量没有出度,那么他中间的所有点都是符合题目要求的点

    代码(多组输入记得每次初始化):

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<iostream>
      4 #include<algorithm>
      5 #include<queue>
      6 #include<map>
      7 #include<vector>
      8 #include<math.h>
      9 #define mem(a,x) memset(a,x,sizeof(a))
     10 using namespace std;
     11 const int maxn=50005;
     12 const int mod=26;
     13 const int INF=0x3f3f3f3f;
     14 struct edge
     15 {
     16     int u,v,next;
     17     bool sign;
     18 } e[maxn*2];
     19 int head[maxn],cnt;
     20 void add_edge(int x,int y)
     21 {
     22     e[cnt].u=x;
     23     e[cnt].v=y;
     24     e[cnt].next=head[x];
     25     head[x]=cnt++;
     26 }
     27 int dfn[maxn],low[maxn],stacks[maxn],top,tot;
     28 int taj;
     29 int belong[maxn],visit[maxn],result[maxn];
     30 vector<int>w[maxn];
     31 void tarjan(int x,int fx)
     32 {
     33     dfn[x]=low[x]=++tot;
     34     stacks[top++]=x;
     35     visit[x]=1;
     36     for(int i=head[x]; i!=-1; i=e[i].next)
     37     {
     38         int v=e[i].v;
     39         if(!dfn[v])
     40         {
     41             tarjan(v,x);
     42             low[x]=min(low[x],low[v]);
     43             if(dfn[x]<low[v])
     44             {
     45                 e[i].sign=1;
     46             }
     47         }
     48         else if(visit[v])
     49         {
     50             low[x]=min(low[x],dfn[v]);
     51         }
     52     }
     53     if(low[x]==dfn[x])
     54     {
     55         int now;
     56         taj++;
     57         w[taj].clear();
     58         do
     59         {
     60             now=stacks[--top];
     61             visit[now]=0;
     62             belong[now]=taj;
     63             w[taj].push_back(now);
     64         }
     65         while(now!=x);
     66     }
     67 }
     68 void tarjan_init(int n)
     69 {
     70     memset(visit,0,sizeof(visit));
     71     memset(low,0,sizeof (low));
     72     memset(dfn,0,sizeof (dfn));
     73     memset(stacks,0,sizeof (stacks));
     74     memset(belong,0,sizeof belong);
     75     top=tot=taj=0;
     76     for(int i=1; i<=n; ++i)
     77     {
     78         if(!dfn[i]) tarjan(i,i);
     79     }
     80 }
     81 vector<int>g[maxn];
     82 int cu[maxn],ru[maxn];
     83 void suodian()
     84 {
     85     memset(cu,0,sizeof(cu));
     86     memset(ru,0,sizeof(ru));
     87     for(int i=1; i<=taj; ++i)
     88         g[i].clear();
     89     for(int i=0; i<cnt; ++i)
     90     {
     91         int u=belong[e[i].u];
     92         int v=belong[e[i].v];
     93         if(u!=v) g[u].push_back(v),cu[u]++,ru[v]++;//printf("%d %d
    ",u,v);
     94     }
     95 }
     96 int vis[maxn];
     97 void init()
     98 {
     99     memset(head,-1,sizeof(head));
    100     cnt=0;
    101 }
    102 int main()
    103 {
    104     int n,m;
    105     while(~scanf("%d",&n))
    106     {
    107         if(n==0) return 0;
    108         scanf("%d",&m);
    109         init();
    110         for(int i=1; i<=m; ++i)
    111         {
    112             int a,b;
    113             scanf("%d%d",&a,&b);
    114             add_edge(a,b);
    115         }
    116         tarjan_init(n);
    117         suodian();
    118         int index=0;
    119         for(int i=1;i<=n;++i)
    120         {
    121             if(cu[belong[i]]==0)
    122                 result[index++]=i;
    123         }
    124         if(index==0)
    125         {
    126             printf("
    ");
    127             continue;
    128         }
    129         sort(result,result+index);
    130         for(int i=0;i<index;++i)
    131             if(i==index-1)
    132                 printf("%d
    ",result[i]);
    133             else printf("%d ",result[i]);
    134     }
    135     return 0;
    136 }
    View Code
  • 相关阅读:
    [bzoj1468]Tree(点分治)
    [bzoj1087]: [SCOI2005]互不侵犯King(状压dp)
    [hdu5628]Clarke and math(dirichlet卷积)
    [bzoj1036]:[ZJOI2008]树的统计Count(树链剖分)
    [bzoj1026][SCOI2009]windy数(前缀和+数位dp)
    洛谷 P1714 切蛋糕(dp+RMQ)
    [hdu3507] Print Article
    [bzoj1597]: [Usaco2008 Mar]土地购买
    php基础二
    php基础
  • 原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/12665925.html
Copyright © 2020-2023  润新知