zoukankan      html  css  js  c++  java
  • 求解强连通分量

    http://codeforces.com/contest/742/problem/C

    http://codeforces.com/contest/711/problem/D

    都是跟强连通分量有关的题目,但是光知道求解强连通分量的算法,是解不出这2道题目的,还需要进一步的分析。

    一般求解强连通分量算法是tarjan算法和双dfs算法,但是,上面的题目都是功能图,functional graph,可以简单的用dfs来做。

    下面贴上tarjan算法,根据需要选择。

     1 #include<bits/stdc++.h>
     2 #define pb push_back
     3 #define FOR(i, n) for (int i = 0; i < (int)n; ++i)
     4 #define dbg(x) cout << #x << " at line " << __LINE__ << " is: " << x << endl
     5 typedef long long ll;
     6 using namespace std;
     7 typedef pair<int, int> pii;
     8 const int maxn = 2e2 + 10;
     9 int n;
    10 int a[110];
    11 int dfn[maxn], low[maxn];
    12 int instack[maxn], stap[maxn];
    13 int stop, dindex;
    14 int bcnt;
    15 int belong[maxn];
    16 int cnt[maxn];
    17 void tarjan(int i) {
    18     int j;
    19     dfn[i] = low[i] = ++dindex;
    20     instack[i] = 1;
    21     stap[++stop] = i;
    22     j = a[i];
    23     if(!dfn[j]) {
    24         tarjan(j);
    25         if(low[j] < low[i])
    26             low[i] = low[j];
    27     } else if(instack[j] && dfn[j] < low[i])
    28         low[i] = dfn[j];
    29     if(dfn[i] == low[i]) {
    30         bcnt++;
    31         do{
    32             j = stap[stop--];
    33             instack[j] = 0;
    34             belong[j] = bcnt;
    35             cnt[bcnt]++;
    36         } while(i != j);
    37     }
    38 }
    39 void solve() {
    40     cin >> n;
    41     for (int i = 1; i <= n; i++) cin >> a[i];
    42     for (int i = 1; i <= n; i++) {
    43         if(!dfn[i])
    44             tarjan(i);
    45     }
    46     bool f = 1;
    47     for (int i = 1; i <= n; i++) {
    48         //cout << i << " " << belong[i] << endl;
    49         if(!belong[i] || (cnt[belong[i] ] == 1 && a[i] != i) ) {
    50             f = 0;
    51             break;
    52         }
    53     }
    54     if(!f) {
    55         cout << -1 << endl;
    56         //cout << "asd" << endl;
    57     }
    58     else {
    59         int res = 1;
    60         for (int i = 1; i <= bcnt; i++) {
    61             if(cnt[i] % 2 == 0) cnt[i] /= 2;
    62             int d = __gcd(res, cnt[i]);
    63             res = 1ll * res * cnt[i] / d;
    64         }
    65         cout << res << endl;
    66 
    67     }
    68 }
    69 int main() {
    70     //freopen("test.in", "r", stdin);
    71     //freopen("test.out", "w", stdout);
    72     ios::sync_with_stdio(0);
    73     cin.tie(0); cout.tie(0);
    74     solve();
    75     return 0;
    76 }

    解法二

     1 #include<bits/stdc++.h>
     2 #define pb push_back
     3 #define FOR(i, n) for (int i = 0; i < (int)n; ++i)
     4 #define dbg(x) cout << #x << " at line " << __LINE__ << " is: " << x << endl
     5 typedef long long ll;
     6 using namespace std;
     7 typedef pair<int, int> pii;
     8 const int maxn = 1e2 + 10;
     9 int n;
    10 int a[maxn];
    11 bool vis[maxn];
    12 int s;
    13 int dfs(int u) {
    14     vis[u] = 1;
    15     int v = a[u];
    16     if(vis[v]) {
    17        if(v != s) return -1;
    18        return 1;
    19     }
    20     int t = dfs(v);
    21     if(t == -1) return -1;
    22     return t + 1;
    23 }
    24 void solve1() {
    25     cin >> n;
    26     for (int i = 1; i <= n; i++) cin >> a[i];
    27     int res = 1;
    28     for (int i = 1; i <= n; i++) {
    29         if(!vis[i]) {
    30             s = i;
    31             int x = dfs(i);
    32             if(x == -1) {
    33                 cout << -1 << endl;
    34                 return;
    35             }
    36             if(x % 2 == 0) x /= 2;
    37             res = 1ll * res * x / __gcd(res, x);
    38         }
    39     }
    40     cout << res << endl;
    41 
    42 }
    43 void solve() {
    44     cin >> n;
    45     for (int i = 1; i <= n; i++) cin >> a[i];
    46     int res = 1;
    47     int cur, sz;
    48     for (int i = 1; i <= n; i++) {
    49         if(vis[i]) continue;
    50         cur = i;
    51         sz = 0;
    52         while(!vis[cur]) {
    53             vis[cur] = 1;
    54             sz++;
    55             cur = a[cur];
    56         }
    57         if(cur != i) {
    58             cout << -1 << endl;
    59             return;
    60         }
    61         if(sz % 2 == 0) sz /= 2;
    62         res = 1ll * res * sz / __gcd(res, sz);
    63     }
    64     cout << res << endl;
    65 }
    66 int main() {
    67     //freopen("test.in", "r", stdin);
    68     //freopen("test.out", "w", stdout);
    69     ios::sync_with_stdio(0);
    70     cin.tie(0); cout.tie(0);
    71     solve();
    72     return 0;
    73 }

    第二题 解法

     1 #include <bits/stdc++.h>
     2 #include <ext/pb_ds/assoc_container.hpp>
     3 #include <ext/pb_ds/tree_policy.hpp>
     4 
     5 using namespace std;
     6 using namespace __gnu_pbds;
     7 
     8 #define fi first
     9 #define se second
    10 #define mp make_pair
    11 #define pb push_back
    12 #define fbo find_by_order
    13 #define ook order_of_key
    14 
    15 typedef long long ll;
    16 typedef pair<int,int> ii;
    17 typedef vector<int> vi;
    18 typedef long double ld; 
    19 typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> pbds;
    20 typedef set<int>::iterator sit;
    21 typedef map<int,int>::iterator mit;
    22 typedef vector<int>::iterator vit;
    23 
    24 const int INF = 1e9 + 7;
    25 const int MOD = 1e9 + 7;
    26 const int N = 1e6 + 3;
    27 
    28 int a[N];
    29 int visited[N];
    30 ll ans;
    31 vector<int> cycles;
    32 ll dp[N];
    33 int cyclecnt;
    34 
    35 void dfs2(int u)
    36 {
    37     cycles[cyclecnt]++;
    38     visited[u] = 3;
    39     if(visited[a[u]] == 3) return ;
    40     dfs2(a[u]);
    41 }
    42 
    43 void dfs(int u)
    44 {
    45     visited[u] = 2;
    46     if(visited[a[u]] == 0)
    47     {
    48         dfs(a[u]);
    49     }
    50     else if(visited[a[u]] == 1)
    51     {
    52         visited[u] = 1;
    53         return ;
    54     }
    55     else
    56     {
    57         cycles.pb(0);
    58         dfs2(u);
    59         cyclecnt++;
    60     }
    61     visited[u] = 1;
    62 }
    63 
    64 int main()
    65 {
    66     //ios_base::sync_with_stdio(0); cin.tie(0);
    67     int n; scanf("%d", &n);
    68     for(int i = 1; i <= n; i++)
    69     {
    70         scanf("%d", a + i);
    71     }
    72     dp[0] = 1;
    73     for(int i = 1; i <= n; i++)
    74     {
    75         dp[i] = (dp[i-1]*2LL)%MOD;
    76     }
    77     ans = 1;
    78     memset(visited, 0, sizeof(visited));
    79     for(int i = 1; i <= n; i++)
    80     {
    81         if(visited[i] == 0)
    82         {
    83             dfs(i);
    84         }
    85     }
    86     ll cnt = n;
    87     for(int i = 0; i < cycles.size(); i++)
    88     {
    89         cnt -= cycles[i];
    90         ans = (ans*(dp[cycles[i]]-2+MOD))%MOD;
    91     }
    92     ans = (ans*dp[cnt])%MOD;
    93     if(ans < 0) ans += MOD;
    94     int ans2 = ans;
    95     printf("%d
    ", ans2);
    96     return 0;
    97 }

    第二题

     1 #include<bits/stdc++.h>
     2 #define pb push_back
     3 #define FOR(i, n) for (int i = 0; i < (int)n; ++i)
     4 #define dbg(x) cout << #x << " at line " << __LINE__ << " is: " << x << endl
     5 typedef long long ll;
     6 using namespace std;
     7 typedef pair<int, int> pii;
     8 const int maxn = 2e5 + 10;
     9 const int mod = 1e9 + 7;
    10 int n;
    11 int a[maxn];
    12 int dfn[maxn], low[maxn];
    13 int counter;
    14 int belong[maxn];
    15 stack<int> sk;
    16 bool instack[maxn];
    17 int conn;
    18 int cnt[maxn];
    19 void tarjan(int u) {
    20     dfn[u] = low[u] = ++counter;
    21     sk.push(u);
    22     instack[u] = 1;
    23     int v = a[u];
    24     if(!dfn[v]) {
    25         tarjan(v);
    26         if(low[v] < low[u])
    27             low[u] = low[v];
    28     } else {
    29         if(instack[v] && low[u] > dfn[v])
    30             low[u] = dfn[v];
    31     }
    32     if(dfn[u] == low[u]) {
    33         conn++;
    34         do {
    35             v = sk.top();
    36             sk.pop();
    37             belong[v] = conn;
    38             cnt[conn]++;
    39             instack[v] = 0;
    40         } while(v != u);
    41     }
    42 }
    43 int f[maxn];
    44 void solve() {
    45     cin >> n;
    46     for (int i = 1; i <= n; i++) cin >> a[i];
    47     for (int i = 1; i <= n; i++) {
    48         if(!dfn[i])
    49             tarjan(i);
    50     }
    51     f[0] = 1;
    52     for (int i = 1; i <= n; i++) {
    53         f[i] = (f[i - 1] * 2) % mod;
    54     }
    55     int s = 0;
    56     ll res = 1;
    57     for (int i = 1; i <= conn; i++) {
    58         //cout << cnt[i] << endl;
    59         if(cnt[i] == 1) {
    60             s++;
    61         } else {
    62             res = (res * (f[cnt[i] ] - 2)) % mod;
    63         }
    64     }
    65     res = (res * f[s]) % mod;
    66     res = (res + mod) % mod;
    67     cout << res << endl;
    68 }
    69 int main() {
    70     //freopen("test.in", "r", stdin);
    71     //freopen("test.out", "w", stdout);
    72     ios::sync_with_stdio(0);
    73     cin.tie(0); cout.tie(0);
    74     solve();
    75     return 0;
    76 }

    这次做的是cf  383 div2.

    http://codeforces.com/contest/742/problem/C 这题点挺多的,分析出是求cycle,然后最后的答案是lcm(lowest common multiple),还有环的个数为偶数,还要除以2。做的时候,没有考虑到时所有情况都要考虑,然后就是lcm。我还以为是最大值,没有仔细分析清楚。

    http://codeforces.com/contest/742/problem/D 简单的背包问题,先用dsu(disjoint set union, find & union)求解每个包,然后使用滚动数组来做。

    http://codeforces.com/contest/742/problem/E 这道题目,不知道怎么做,看题解,才知道是二分图,然后染色来做,对二分图不是很了解,这里只是简单的mark一下。学习一下怎么保证pair对不同,同时连续的3个中,至少2个不同,怎么进行保证,全部构成边,只需要保证边的2端不同即可。然后就是染色,边的2端不同。

  • 相关阅读:
    Edit Distance编辑距离(NM tag)- sam/bam格式解读进阶
    《开讲啦》 20160910 颜宁:女科学家去哪儿了?
    pysam
    Python项目实战
    最小二乘估计法
    最大似然估计(Maximum Likelihood,ML)
    HMM隐马尔科夫模型
    贝叶斯推断|朴素贝叶斯分类|贝叶斯定理
    解决“tar:Exiting with failure status due to previous errors”【转】
    df -h执行卡住不动问题解决【转】
  • 原文地址:https://www.cnblogs.com/y119777/p/6142637.html
Copyright © 2011-2022 走看看