zoukankan      html  css  js  c++  java
  • tarjan

    hdu1269 迷宫城堡 http://acm.hdu.edu.cn/showproblem.php?pid=1269

    模板。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<stack>
     4 #define mt(a,b) memset(a,b,sizeof(a))
     5 using namespace std;
     6 class Tarjan{///有向图强连通分量缩点
     7     static const int ME=100010;///边的个数
     8     static const int MV=10010;///点的个数
     9     int Index,Bcnt,num[MV],belong[MV],dfn[MV],low[MV];
    10     bool instack[MV];
    11     stack<int> s;
    12     void tarjan(int u) {
    13         dfn[u]=low[u]=++Index;
    14         instack[u]=true;
    15         s.push(u);
    16         int v;
    17         for(int i=g.head[u]; ~i; i=g.e[i].next) {
    18             v=g.e[i].v;
    19             if(!dfn[v]) {
    20                 tarjan(v);
    21                 low[u]=min(low[u],low[v]);
    22             } else if(instack[v]) {
    23                 low[u]=min(low[u],dfn[v]);
    24             }
    25         }
    26         if(dfn[u]==low[u]) {
    27             Bcnt++;
    28             do {
    29                 v=s.top();
    30                 s.pop();
    31                 instack[v]=false;
    32                 belong[v]=Bcnt;
    33                 num[Bcnt]++;
    34             } while(u!=v);
    35         }
    36     }
    37     struct G {
    38         struct E {
    39             int u,v,next;
    40         } e[ME];
    41         int le,head[MV];
    42         void init() {
    43             le=0;
    44             mt(head,-1);
    45         }
    46         void add(int u,int v) {
    47             e[le].u=u;
    48             e[le].v=v;
    49             e[le].next=head[u];
    50             head[u]=le++;
    51         }
    52     } g;
    53 public:
    54     void init() {
    55         g.init();
    56         Index=Bcnt=0;
    57         mt(num,0);
    58         mt(dfn,0);
    59         mt(low,0);
    60         mt(instack,0);
    61         while(!s.empty()) s.pop();
    62     }
    63     void add(int u,int v) {
    64         g.add(u,v);
    65     }
    66     void solve(int n) {///传入点数,点下标1开始
    67         for(int i=1; i<=n; i++) {
    68             if(!dfn[i]) {
    69                 tarjan(i);
    70             }
    71         }
    72     }
    73     int getbcnt() {///强连通分量的个数
    74         return Bcnt;
    75     }
    76     int getbelong(int id) {///属于哪个分量,分量下标1开始
    77         return belong[id];
    78     }
    79     int getnum(int id) {///某个分量的点的个数
    80         return num[id];
    81     }
    82 }tarjan;
    83 int main(){
    84     int n,m,x,y;
    85     while(~scanf("%d%d",&n,&m),n+m){
    86         tarjan.init();
    87         while(m--){
    88             scanf("%d%d",&x,&y);
    89             tarjan.add(x,y);
    90         }
    91         tarjan.solve(n);
    92         if(tarjan.getbcnt()==1) puts("Yes");
    93         else puts("No");
    94     }
    95     return 0;
    96 }
    View Code

     ZOJ Problem Set - 3795  Grouping  http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5303

    缩点加最长路dp。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<stack>
      4 #define mt(a,b) memset(a,b,sizeof(a))
      5 using namespace std;
      6 class Tarjan{///有向图强连通分量缩点
      7     static const int ME=300010;///边的个数
      8     static const int MV=100010;///点的个数
      9     int Index,Bcnt,num[MV],belong[MV],dfn[MV],low[MV];
     10     bool instack[MV];
     11     stack<int> s;
     12     void tarjan(int u) {
     13         dfn[u]=low[u]=++Index;
     14         instack[u]=true;
     15         s.push(u);
     16         int v;
     17         for(int i=g.head[u]; ~i; i=g.e[i].next) {
     18             v=g.e[i].v;
     19             if(!dfn[v]) {
     20                 tarjan(v);
     21                 low[u]=min(low[u],low[v]);
     22             } else if(instack[v]) {
     23                 low[u]=min(low[u],dfn[v]);
     24             }
     25         }
     26         if(dfn[u]==low[u]) {
     27             Bcnt++;
     28             do {
     29                 v=s.top();
     30                 s.pop();
     31                 instack[v]=false;
     32                 belong[v]=Bcnt;
     33                 num[Bcnt]++;
     34             } while(u!=v);
     35         }
     36     }
     37 public:
     38     struct G {
     39         struct E {
     40             int u,v,next;
     41         } e[ME];
     42         int le,head[MV];
     43         void init() {
     44             le=0;
     45             mt(head,-1);
     46         }
     47         void add(int u,int v) {
     48             e[le].u=u;
     49             e[le].v=v;
     50             e[le].next=head[u];
     51             head[u]=le++;
     52         }
     53     } g;
     54 public:
     55     void init() {
     56         g.init();
     57         Index=Bcnt=0;
     58         mt(num,0);
     59         mt(dfn,0);
     60         mt(low,0);
     61         mt(instack,0);
     62         while(!s.empty()) s.pop();
     63     }
     64     void add(int u,int v) {
     65         g.add(u,v);
     66     }
     67     void solve(int n) {///传入点数,点下标1开始
     68         for(int i=1; i<=n; i++) {
     69             if(!dfn[i]) {
     70                 tarjan(i);
     71             }
     72         }
     73     }
     74     int getbcnt() {///强连通分量的个数
     75         return Bcnt;
     76     }
     77     int getbelong(int id) {///属于哪个分量,分量下标1开始
     78         return belong[id];
     79     }
     80     int getnum(int id) {///某个分量的点的个数
     81         return num[id];
     82     }
     83 }tarjan;
     84 static const int ME=300010;///边的个数
     85 static const int MV=100010;///点的个数
     86 struct G {
     87     struct E {
     88         int u,v,next;
     89     } e[ME];
     90     int le,head[MV];
     91     void init() {
     92         le=0;
     93         mt(head,-1);
     94     }
     95     void add(int u,int v) {
     96         e[le].u=u;
     97         e[le].v=v;
     98         e[le].next=head[u];
     99         head[u]=le++;
    100     }
    101 } gx;
    102 int dp[MV];
    103 int dfs(int u){
    104     if(dp[u]!=-1) return dp[u];
    105     int tmp=tarjan.getnum(u);
    106     dp[u]=tmp;
    107     for(int i=gx.head[u];~i;i=gx.e[i].next){
    108         int v=gx.e[i].v;
    109         dp[u]=max(dp[u],tmp+dfs(v));
    110     }
    111     return dp[u];
    112 }
    113 int main(){
    114     int n,m,u,v;
    115     while(~scanf("%d%d",&n,&m)){
    116         tarjan.init();
    117         for(int i=0;i<m;i++){
    118             scanf("%d%d",&u,&v);
    119             tarjan.add(u,v);
    120         }
    121         tarjan.solve(n);
    122         gx.init();
    123         for(int i=0;i<tarjan.g.le;i++){
    124             u=tarjan.g.e[i].u;
    125             v=tarjan.g.e[i].v;
    126             u=tarjan.getbelong(u);
    127             v=tarjan.getbelong(v);
    128             if(u!=v){
    129                 gx.add(u,v);
    130             }
    131         }
    132         mt(dp,-1);
    133         int ans=0;
    134         for(int i=1;i<=tarjan.getbcnt();i++){
    135             ans=max(ans,dfs(i));
    136         }
    137         printf("%d
    ",ans);
    138     }
    139     return 0;
    140 }
    View Code

    缩点 

    cf427c   C. Checkposts  http://codeforces.com/problemset/problem/427/C

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<stack>
      5 #define mt(a,b) memset(a,b,sizeof(a))
      6 using namespace std;
      7 const int M=100010;
      8 const int mod=1000000007;
      9 typedef __int64 LL;
     10 class Tarjan{///有向图强连通分量缩点
     11     static const int ME=M*3;///边的个数
     12     static const int MV=M;///点的个数
     13     int Index,Bcnt,num[MV],belong[MV],dfn[MV],low[MV];
     14     bool instack[MV];
     15     stack<int> s;
     16     void tarjan(int u) {
     17         dfn[u]=low[u]=++Index;
     18         instack[u]=true;
     19         s.push(u);
     20         int v;
     21         for(int i=g.head[u]; ~i; i=g.e[i].next) {
     22             v=g.e[i].v;
     23             if(!dfn[v]) {
     24                 tarjan(v);
     25                 low[u]=min(low[u],low[v]);
     26             } else if(instack[v]) {
     27                 low[u]=min(low[u],dfn[v]);
     28             }
     29         }
     30         if(dfn[u]==low[u]) {
     31             Bcnt++;
     32             do {
     33                 v=s.top();
     34                 s.pop();
     35                 instack[v]=false;
     36                 belong[v]=Bcnt;
     37                 num[Bcnt]++;
     38             } while(u!=v);
     39         }
     40     }
     41     struct G {
     42         struct E {
     43             int u,v,next;
     44         } e[ME];
     45         int le,head[MV];
     46         void init() {
     47             le=0;
     48             mt(head,-1);
     49         }
     50         void add(int u,int v) {
     51             e[le].u=u;
     52             e[le].v=v;
     53             e[le].next=head[u];
     54             head[u]=le++;
     55         }
     56     } g;
     57 public:
     58     void init() {
     59         g.init();
     60         Index=Bcnt=0;
     61         mt(num,0);
     62         mt(dfn,0);
     63         mt(low,0);
     64         mt(instack,0);
     65         while(!s.empty()) s.pop();
     66     }
     67     void add(int u,int v) {
     68         g.add(u,v);
     69     }
     70     void solve(int n) {///传入点数,点下标1开始
     71         for(int i=1; i<=n; i++) {
     72             if(!dfn[i]) {
     73                 tarjan(i);
     74             }
     75         }
     76     }
     77     int getbcnt() {///强连通分量的个数
     78         return Bcnt;
     79     }
     80     int getbelong(int id) {///属于哪个分量,分量下标1开始
     81         return belong[id];
     82     }
     83     int getnum(int id) {///某个分量的点的个数
     84         return num[id];
     85     }
     86 }gx;
     87 int val[M];
     88 struct G{
     89     int val,id;
     90 }g[M];
     91 bool cmp(G a,G b){
     92     if(a.id==b.id) return a.val<b.val;
     93     return a.id<b.id;
     94 }
     95 int main(){
     96     int n,m,x,y;
     97     while(~scanf("%d",&n)){
     98         gx.init();
     99         for(int i=1;i<=n;i++){
    100             scanf("%d",&val[i]);
    101         }
    102         scanf("%d",&m);
    103         while(m--){
    104             scanf("%d%d",&x,&y);
    105             gx.add(x,y);
    106         }
    107         gx.solve(n);
    108 
    109         LL sum=0;
    110         LL ans=1;
    111         for(int i=1;i<=n;i++){
    112             g[i].val=val[i];
    113             g[i].id=gx.getbelong(i);
    114         }
    115         sort(g+1,g+1+n,cmp);
    116         g[0].id=-1;
    117         for(int i=1;i<=n;i++){
    118             if(g[i].id!=g[i-1].id){
    119                 sum+=(LL)g[i].val;
    120                 int num=0;
    121                 for(int j=i;j<=n;j++){
    122                     if(g[i].id==g[j].id&&g[i].val==g[j].val){
    123                         num++;
    124                     }
    125                     else{
    126                         i=j-1;
    127                         break;
    128                     }
    129                 }
    130                 ans*=num;
    131                 ans%=mod;
    132             }
    133         }
    134         printf("%I64d %I64d
    ",sum,ans);
    135     }
    136     return 0;
    137 }
    View Code

    end

  • 相关阅读:
    c++ 视频和教程下载站点
    SQL超时解决方法
    初学者必备:C++经典入门详细教程
    人生致命的八个经典问题
    字长与字节
    typedef用法(三)
    遍历搜索注册表
    数据库连接字符串大全 之 SQL服务器篇
    十五个步骤收获学习的习惯
    谈基于.net平台windows开发中的模式窗体.NET教程,.NET Framework
  • 原文地址:https://www.cnblogs.com/gaolzzxin/p/3937155.html
Copyright © 2011-2022 走看看