zoukankan      html  css  js  c++  java
  • UVA

    题目链接

    题意:从有向图G中找到一个最大的点集,使得该点集中任意两个结点u,v满足u可达v或v可达u。

    解法:先把同处于一个强连通分量中的结点合并(缩点),得到一张DAG图,在DAG上dp即可。

    感觉自己的建图写得好丑啊,一直在纠结用数组还是结构体~~

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 const int N=1e5+10;
     5 int head[N],nxt[N],to[N],ne,n,m;
     6 void addedge(int* head,int u,int v) {
     7     nxt[ne]=head[u],to[ne]=v,head[u]=ne++;
     8 }
     9 int dfn[N],low[N],scc[N],sta[N],nscc,nsta,tot,siz[N];
    10 int head2[N];
    11 
    12 void dfs(int u) {
    13     dfn[u]=low[u]=++tot;
    14     sta[nsta++]=u;
    15     for(int e=head[u]; ~e; e=nxt[e]) {
    16         int v=to[e];
    17         if(!dfn[v])dfs(v),low[u]=min(low[u],low[v]);
    18         else if(!scc[v])low[u]=min(low[u],dfn[v]);
    19     }
    20     if(low[u]==dfn[u]) {
    21         nscc++;
    22         for(; !scc[u]; scc[sta[--nsta]]=nscc);
    23     }
    24 }
    25 
    26 void getscc() {
    27     memset(dfn,0,sizeof dfn);
    28     memset(scc,0,sizeof scc);
    29     tot=nscc=nsta=0;
    30     for(int i=1; i<=n; ++i)if(!dfn[i])dfs(i);
    31 }
    32 
    33 int d[N];
    34 
    35 int dp(int u) {
    36     if(~d[u])return d[u];
    37     int x=0;
    38     for(int e=head2[u]; ~e; e=nxt[e]) {
    39         int v=to[e];
    40         x=max(x,dp(v));
    41     }
    42     return d[u]=siz[u]+x;
    43 }
    44 
    45 int main() {
    46     int T;
    47     scanf("%d",&T);
    48     while(T--) {
    49         memset(head,-1,sizeof head);
    50         memset(head2,-1,sizeof head2);
    51         ne=0;
    52         scanf("%d%d",&n,&m);
    53         while(m--) {
    54             int u,v;
    55             scanf("%d%d",&u,&v);
    56             addedge(head,u,v);
    57         }
    58         getscc();
    59         memset(siz,0,sizeof siz);
    60         for(int u=1; u<=n; ++u)siz[scc[u]]++;
    61         for(int u=1; u<=n; ++u) {
    62             for(int e=head[u]; ~e; e=nxt[e]) {
    63                 int v=to[e];
    64                 if(scc[u]!=scc[v])addedge(head2,scc[u],scc[v]);
    65             }
    66         }
    67         memset(d,-1,sizeof d);
    68         int ans=0;
    69         for(int i=1; i<=nscc; ++i)ans=max(ans,dp(i));
    70         printf("%d
    ",ans);
    71     }
    72     return 0;
    73 }
  • 相关阅读:
    lightoj 1151 Snakes and Ladders 期望 高斯消元
    lightoj 1104 Birthday Paradox 概率
    lightoj 1079 Just another Robbery 概率 背包
    集合的划分
    线性筛法
    学姐出的毒奶题之yjj
    [poj] 1149 PIGS || 最大流经典题目
    [poj] 3057 Evacuation
    [poj] 1273 Drainage Ditches
    [poj] 2891 Strange Way to Express Integers
  • 原文地址:https://www.cnblogs.com/asdfsag/p/10281549.html
Copyright © 2011-2022 走看看