zoukankan      html  css  js  c++  java
  • bzoj 1064

    题意:戳这里

    思路:很明显是一个图论模型。。

            就两种图形:

                1、图中存在环,那么就是所有环的gcd为最大答案。gcd的大于3的最小约数为最小答案

                2、不存在环,那么是每个弱连通块的最长链之和为最大答案,最小答案为3。。

           但是这一题最关键的是实现,实现技巧太赞了。。

           首先,我们可以把每条有向边(u, v)拆成(u, v, 1), (v,  u, -1)

           那么对于第二情况,对于每一个联通块直接随便找一个bfs,然后最长链就是maxdist-mindist+1

           对于第一种情况,可能出现环套环的情况,这样处理起来很麻烦。。

           但实际上很容易发现对于大环套小环实际上大环可以转换成大环-小环剩下的小圈求gcd。。注意这里的小圈不一定是环,因为边有正有负。。

           这样正好处理可以一遍dfs处理。。

          说得很抽象。。直接看这位神犇博客的图吧。。

    code:

     1 #include <bits/stdc++.h>
     2 #define M0(a) memset(a, 0, sizeof(a))
     3 #define x first
     4 #define y second
     5 #define vii vector< pair<int, int> >::iterator 
     6 using namespace std;
     7 const int maxn = 100010;
     8 vector< pair<int, int> > e[maxn];
     9 int n, m;
    10 
    11 
    12 int vis[maxn], d[maxn];
    13 void init(){
    14      for (int i = 0; i <= n; ++i) e[i].clear();
    15      int u, v;
    16      pair<int, int> tmp;
    17      for (int i = 0; i < m; ++i){
    18           scanf("%d%d", &u, &v);
    19           tmp.x = v, tmp.y = 1;
    20           e[u].push_back(tmp);
    21           tmp.x = u, tmp.y = -1;
    22           e[v].push_back(tmp);
    23      }
    24 }
    25 
    26 int ans;
    27 void gao1(){
    28      int ans1 = ans, ans2 = ans;
    29      if (ans1 < 3){
    30           puts("-1 -1"); return;
    31      }
    32      for (int j = 3; j <= ans; ++j) if (ans % j == 0){
    33          ans2 = j; break;
    34      }
    35      printf("%d %d
    ", ans1, ans2);
    36 }
    37 
    38 
    39 int bfs(const int s){
    40     queue<int> q;
    41     q.push(s), d[s] = 0, vis[s] = 1;
    42     int u, v, w;
    43     int maxdist= 0, mindist = 0;
    44     while (!q.empty()){
    45         u = q.front();
    46         q.pop();
    47         for (vii it = e[u].begin(); it != e[u].end(); ++it){
    48               v = it->x, w = it->y;
    49               if (vis[v]) continue;
    50               d[v] = d[u] + w;
    51               if (d[v] > maxdist) maxdist = d[v];
    52               if (d[v] < mindist) mindist = d[v];
    53               vis[v] = 1, q.push(v);
    54         }
    55     }
    56     return maxdist - mindist + 1;
    57 }
    58 
    59 void gao2(){
    60      M0(vis), M0(d);
    61      int ans1 = 0;
    62      for (int i = 1; i <= n; ++i) if (!vis[i])
    63          ans1 += bfs(i);
    64      if (ans1 < 3) puts("-1 -1");
    65      else printf("%d %d
    ", ans1, 3);
    66 }
    67 
    68 void dfs(int u){
    69       vis[u] = 1;
    70       int v;
    71       for (vii it = e[u].begin(); it != e[u].end(); ++it){
    72             v = it->x;
    73             if (vis[v])
    74                  ans = __gcd(ans, abs(d[u] + it->y - d[v]));     
    75             else
    76                  d[v] = d[u] + it->y, dfs(v);
    77       }
    78 }
    79 
    80 void solve(){
    81      M0(vis), M0(d);
    82      ans = 0;
    83      for (int i = 1; i <= n; ++i) if (!vis[i])
    84            dfs(i);
    85      if (ans) gao1();
    86      else gao2();
    87 }
    88 
    89 int main(){
    90     freopen("a.in", "r", stdin);
    91     while (scanf("%d%d", &n, &m) != EOF){
    92          init();
    93          solve();
    94     }       
    95 }
    View Code

           

  • 相关阅读:
    Sqli-labs less 36
    python3操作mysql数据库增删改查
    python3连接MySQL数据库
    修改(python) mysql 数据库 使其可以支持插入中文
    十九 Django框架,发送邮件
    十八 Django框架,生成二维码
    十七 Django框架,文件上传
    十六 Django框架,信号
    十五 Django框架,缓存
    十四 Django框架,中间件
  • 原文地址:https://www.cnblogs.com/yzcstc/p/4067992.html
Copyright © 2011-2022 走看看