• UVA


    给定一个图,求一个节点数目最多的团,对于其中任意两个节点u,v至少存在一条这样的路径使得u到v,或者v到u。

    分析: 先求出强连通分量,然后缩点,构成一个scc图,然后求一条最长的路,每个节点的权重即为该强连通分量的节点数目,由于是DAG, 所以可以用dp或者spfa,一开始用记忆化搜索竟然TLE,想也想不通,后来改成spfa,以0为起点,然后求出距离0的最大距离。

    spfa:

      1 #include <iostream>
      2 #include <sstream>
      3 #include <cstdio>
      4 #include <climits>
      5 #include <cstring>
      6 #include <cstdlib>
      7 #include <string>
      8 #include <stack>
      9 #include <map>
     10 #include <cmath>
     11 #include <vector>
     12 #include <queue>
     13 #include <algorithm>
     14 #define esp 1e-6
     15 #define pi acos(-1.0)
     16 #define pb push_back
     17 #define mp(a, b) make_pair((a), (b))
     18 #define in  freopen("in.txt", "r", stdin);
     19 #define out freopen("out.txt", "w", stdout);
     20 #define print(a) printf("%d
    ",(a));
     21 #define bug puts("********))))))");
     22 #define stop  system("pause");
     23 #define Rep(i, c) for(__typeof(c.end()) i = c.begin(); i != c.end(); i++)
     24 
     25 #define inf 0x0f0f0f0f
     26 
     27 using namespace std;
     28 typedef long long  LL;
     29 typedef vector<int> VI;
     30 typedef pair<int, int> pii;
     31 typedef vector<pii,int> VII;
     32 typedef vector<int>:: iterator IT;
     33 const int maxn = 5000;
     34 int pre[maxn], lowlink[maxn], sccno[maxn], dfs_clock, scc_cnt;
     35 int a[maxn], dp[maxn], dis[maxn], inq[maxn];
     36 VI g[maxn], G[maxn];
     37 stack<int> S;
     38 void dfs(int u)
     39 {
     40     S.push(u);
     41     lowlink[u] = pre[u] = ++dfs_clock;
     42     for(int i = 0; i < g[u].size(); i++)
     43     {
     44         int  v = g[u][i];
     45         if(!pre[v])
     46         {
     47             dfs(v);
     48             lowlink[u] = min(lowlink[u], lowlink[v]);
     49         }
     50         else if(!sccno[v])
     51         {
     52             lowlink[u] = min(lowlink[u], pre[v]);
     53         }
     54     }
     55     int cnt= 0;
     56     if(lowlink[u] == pre[u])
     57     {
     58         scc_cnt++;
     59         for(;;)
     60         {
     61             int x = S.top();
     62             S.pop();
     63             cnt++;
     64             sccno[x] = scc_cnt;
     65             if(x ==  u)
     66             {
     67                 a[scc_cnt] = cnt;
     68                 break;
     69             }
     70         }
     71     }
     72 }
     73 void find_scc(int n)
     74 {
     75     memset(pre, 0, sizeof(pre));
     76     memset(sccno, 0, sizeof(sccno));
     77 
     78     dfs_clock = scc_cnt = 0;
     79     for(int i = 0; i < n; i++)
     80         if(!pre[i]) dfs(i);
     81 }
     82 void spfa(void)
     83 {
     84     memset(inq, 0, sizeof(inq));
     85     memset(dis, 0, sizeof(dis));
     86     queue<int> q;
     87     inq[0] = 1;
     88     q.push(0);
     89     while(!q.empty())
     90     {
     91         int u = q.front();
     92         q.pop();
     93         inq[u] = 0;
     94         for(int i = 0; i < G[u].size(); i++)
     95         {
     96             int v = G[u][i];
     97             if(dis[v] < dis[u] + a[v])
     98                 if(dis[v] = dis[u] + a[v], !inq[v])
     99                     inq[v] = 1, q.push(v);
    100         }
    101     }
    102 }
    103 int main(void)
    104 {
    105     int n, m;
    106     int T;
    107     for(int t = scanf("%d", &T); t <= T; t++)
    108     {
    109         for(int i = 0; i < maxn; i++)
    110             g[i].clear(), G[i].clear();
    111         scanf("%d%d", &n, &m);
    112         memset(a, 0, sizeof(a));
    113         while(m--)
    114         {
    115             int u, v;
    116             scanf("%d%d", &u, &v);
    117             u--, v--;
    118             g[u].pb(v);
    119         }
    120         find_scc(n);
    121         for(int u = 0; u < n; u++)
    122             for(int i = 0; i < g[u].size(); i++)
    123             {
    124                 int v = g[u][i];
    125                 if(sccno[v] != sccno[u])
    126                     G[sccno[u]].pb(sccno[v]);
    127             }
    128         for(int i = 1; i <= scc_cnt; i++)
    129             G[0].pb(i);
    130         spfa();
    131         int ans = 0;
    132         for(int i = 1; i <= scc_cnt; i++)
    133             ans = max(ans, dis[i]);
    134         printf("%d
    ", ans);
    135     }
    136     return 0;
    137 }
    View Code

    下面是dp代码,一开始用的邻接矩阵存储关系图,后来改成邻接表果断过了,以后要注意了,尽量用邻接表

      1 #include <iostream>
      2 #include <sstream>
      3 #include <cstdio>
      4 #include <climits>
      5 #include <cstring>
      6 #include <cstdlib>
      7 #include <string>
      8 #include <stack>
      9 #include <map>
     10 #include <cmath>
     11 #include <vector>
     12 #include <queue>
     13 #include <algorithm>
     14 #define esp 1e-6
     15 #define pi acos(-1.0)
     16 #define pb push_back
     17 #define mp(a, b) make_pair((a), (b))
     18 #define in  freopen("in.txt", "r", stdin);
     19 #define out freopen("out.txt", "w", stdout);
     20 #define print(a) printf("%d
    ",(a));
     21 #define bug puts("********))))))");
     22 #define stop  system("pause");
     23 #define Rep(i, c) for(__typeof(c.end()) i = c.begin(); i != c.end(); i++)
     24 
     25 #define inf 0x0f0f0f0f
     26 
     27 using namespace std;
     28 typedef long long  LL;
     29 typedef vector<int> VI;
     30 typedef pair<int, int> pii;
     31 typedef vector<pii,int> VII;
     32 typedef vector<int>:: iterator IT;
     33 const int maxn = 5000;
     34 int pre[maxn], lowlink[maxn], sccno[maxn], dfs_clock, scc_cnt;
     35 int a[maxn], dp[maxn], dis[maxn], inq[maxn];
     36 VI g[maxn], G[maxn];
     37 stack<int> S;
     38 void dfs(int u)
     39 {
     40     S.push(u);
     41     lowlink[u] = pre[u] = ++dfs_clock;
     42     for(int i = 0; i < g[u].size(); i++)
     43     {
     44         int  v = g[u][i];
     45         if(!pre[v])
     46         {
     47             dfs(v);
     48             lowlink[u] = min(lowlink[u], lowlink[v]);
     49         }
     50         else if(!sccno[v])
     51         {
     52             lowlink[u] = min(lowlink[u], pre[v]);
     53         }
     54     }
     55     int cnt= 0;
     56     if(lowlink[u] == pre[u])
     57     {
     58         scc_cnt++;
     59         for(;;)
     60         {
     61             int x = S.top();
     62             S.pop();
     63             cnt++;
     64             sccno[x] = scc_cnt;
     65             if(x ==  u)
     66             {
     67                 a[scc_cnt] = cnt;
     68                 break;
     69             }
     70         }
     71     }
     72 }
     73 void find_scc(int n)
     74 {
     75     memset(pre, 0, sizeof(pre));
     76     memset(sccno, 0, sizeof(sccno));
     77 
     78     dfs_clock = scc_cnt = 0;
     79     for(int i = 0; i < n; i++)
     80         if(!pre[i]) dfs(i);
     81 }
     82 void spfa(void)
     83 {
     84     memset(inq, 0, sizeof(inq));
     85     memset(dis, 0, sizeof(dis));
     86     queue<int> q;
     87     inq[0] = 1;
     88     q.push(0);
     89     while(!q.empty())
     90     {
     91         int u = q.front();
     92         q.pop();
     93         inq[u] = 0;
     94         for(int i = 0; i < G[u].size(); i++)
     95         {
     96             int v = G[u][i];
     97             if(dis[v] < dis[u] + a[v])
     98                 if(dis[v] = dis[u] + a[v], !inq[v])
     99                     inq[v] = 1, q.push(v);
    100         }
    101     }
    102 }
    103 int main(void)
    104 {
    105     int n, m;
    106     int T;
    107     for(int t = scanf("%d", &T); t <= T; t++)
    108     {
    109         for(int i = 0; i < maxn; i++)
    110             g[i].clear(), G[i].clear();
    111         scanf("%d%d", &n, &m);
    112         memset(a, 0, sizeof(a));
    113         while(m--)
    114         {
    115             int u, v;
    116             scanf("%d%d", &u, &v);
    117             u--, v--;
    118             g[u].pb(v);
    119         }
    120         find_scc(n);
    121         for(int u = 0; u < n; u++)
    122             for(int i = 0; i < g[u].size(); i++)
    123             {
    124                 int v = g[u][i];
    125                 if(sccno[v] != sccno[u])
    126                     G[sccno[u]].pb(sccno[v]);
    127             }
    128         for(int i = 1; i <= scc_cnt; i++)
    129             G[0].pb(i);
    130         spfa();
    131         int ans = 0;
    132         for(int i = 1; i <= scc_cnt; i++)
    133             ans = max(ans, dis[i]);
    134         printf("%d
    ", ans);
    135     }
    136     return 0;
    137 }
    View Code
  • 相关阅读:
    linux c编程错误汇总
    linux 相对路径
    内存池版本4多线程可变大小对象的内存池
    2. D3DBlankWindow添加透视投影矩阵
    1. D3DBalnkWindow
    内存池版本3单线程可变大小对象的内存池
    内联函数提高程序性能
    代码优化
    STL总结
    内存池版本2单线程固定大小对象的内存池
  • 原文地址:https://www.cnblogs.com/rootial/p/3337805.html
Copyright © 2020-2023  润新知