zoukankan      html  css  js  c++  java
  • poj 2762【Going from u to v or from v to u?】

    先用Tarjan求出强连通分量,其他算法也可以的,再缩点,然后从入度为0的点开始暴搜,如果深度达到强连通分量的个数即可行。这一题一定要注意一点:我用cin的时候TLE,该scanf就好了。。。

    View Code
      1 #include <cstdio>
      2 #include <cstring>
      3 #include <vector>
      4 using namespace std;
      5 
      6 const int maxN = 1000 + 10;
      7 vector<int> edge[maxN];
      8 int low[maxN];
      9 int stack[maxN],top;
     10 int del[maxN];
     11 int DFN[maxN];
     12 int ComNum;
     13 int cnt;
     14 
     15 bool flag;
     16 bool in[maxN];
     17 vector<int> sedge[maxN];
     18 
     19 void Tarjan(int x)
     20 {
     21     stack[top ++] = x;
     22     low[x] = DFN[x] = cnt ++;
     23 
     24     int len = edge[x].size();
     25     for(int i = 0;i < len;i ++)
     26     {
     27         int u = edge[x][i];
     28         if(!DFN[u])
     29         {
     30             Tarjan(u);
     31             if(low[x] > low[u]) low[x] = low[u];
     32         }
     33         else if(!del[u])
     34         {
     35             if(low[x] > DFN[u]) low[x] = DFN[u];
     36         }
     37     }
     38 
     39     if(DFN[x] == low[x])
     40     {
     41         ComNum ++;
     42         do
     43         {
     44             del[stack[top-1]] = ComNum;
     45         }while(stack[--top] != x);
     46     }
     47 }
     48 
     49 void UseTarjan(int n)
     50 {
     51     memset(DFN,0,sizeof(DFN));
     52     memset(del,0,sizeof(del));
     53     ComNum = 0;
     54     top = 0;
     55     cnt = 1;
     56     for(int i = 1;i <= n;i ++)
     57     {
     58         if(!DFN[i])
     59         {
     60             Tarjan(i);
     61         }
     62     }
     63 }
     64 
     65 void dfs(int k,int cc)
     66 {
     67     in[k] = true;
     68     //cc ++;
     69     if(cc == ComNum)
     70     {
     71         flag = true;
     72         return;
     73     }
     74     int len = sedge[k].size();
     75     for(int i = 0;i < len;i ++)
     76     {
     77         if(!in[sedge[k][i]])
     78         {
     79             dfs(sedge[k][i],cc+1);
     80         }
     81         if(flag)
     82         return;
     83     }
     84 }
     85 
     86 int main()
     87 {
     88     int n,m;
     89     int cases;
     90     scanf("%d",&cases);
     91     while(cases --)
     92     {
     93         scanf("%d%d",&n,&m);
     94         for(int i = 0;i <= n;i ++)
     95         {
     96             edge[i].clear();
     97             sedge[i].clear();
     98         }
     99 
    100         for(int i = 0;i < m;i ++)
    101         {
    102             int u,v;
    103            scanf("%d%d",&u,&v);
    104             edge[u].push_back(v);
    105         }
    106         UseTarjan(n);
    107         if(ComNum == 1)
    108         {
    109             printf("Yes\n");
    110             continue;
    111         }
    112         int i = 1;
    113         memset(in,false,sizeof(in));
    114         for(;i <= n;i ++)
    115         {
    116             int len = edge[i].size();
    117             for(int j = 0;j < len;j ++)
    118             {
    119                 if(del[i] != del[edge[i][j]])
    120                 {
    121                     in[del[edge[i][j]]] = true;
    122                     sedge[del[i]].push_back(del[edge[i][j]]);//将缩点构成图
    123                 }
    124             }
    125         }
    126         int t = 0;
    127         int k = 0;
    128         for(i = 1;i <= ComNum;i ++)
    129         {
    130             if(!in[i])//寻找入度为0的点
    131             {
    132                 t ++;
    133                 k = i;//记录下入度为0的点
    134             }
    135         }
    136         if(t > 1)//如果入度为0的点超过一个这几个点无法到达
    137         {
    138             printf("No\n");
    139             continue;
    140         }
    141 
    142         flag = false;
    143         memset(in,false,sizeof(in));
    144         dfs(k,1);//从入度为0的点开始搜
    145         if(flag)
    146         {
    147             printf("Yes\n");
    148         }
    149         else
    150         {
    151             printf("No\n");
    152         }
    153     }
    154 
    155     return 0;
    156 }
  • 相关阅读:
    Android:控件GridView的使用
    Android:监听ListView
    Android:控件ListView列表项与适配器结合使用
    Android:删除模拟器中没用的应用
    Android:Activity之间跳转和参数传递
    Android:常见错误提示
    删除appcompat_v7会出很多错误
    Android工具:延展图片NinePatch
    Android:布局实例之模仿QQ登录界面
    Android:android:gravity 和 android:layout_Gravity 的区别
  • 原文地址:https://www.cnblogs.com/Shirlies/p/2677895.html
Copyright © 2011-2022 走看看