码迷,mamicode.com
首页 > 其他好文 > 详细

codeforces 698b 图论

时间:2016-09-20 22:37:19      阅读:252      评论:0      收藏:0      [点我收藏+]

标签:

题意: 给一串数字a1~an,ai表示i与ai相连,问给出的数组经过最少数量的更改能形成一颗树

题解:分析可知组成的只能由三种非连通图构成,点,不含环链,含环链,含环链必定只可能还有一个环

   统计三种的数量,点和不含环链必定会有父节点为自身的点,含环链用强连通跑一跑,最后把这三种图连到一个节点上就行

   注意一下只含有含环链的情况

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cmath>
  4 #include <iostream>
  5 #include <algorithm>
  6 #include <map>
  7 #include <vector>
  8 #include <queue>
  9 using namespace std;
 10 #define EPS 1e-10
 11 typedef long long ll;
 12 const int maxn = 2e5 + 10;
 13 const int INF = 1e9 ;
 14 const int N = maxn;
 15 const int M = maxn;
 16 
 17 struct Edge {
 18     int to, next;
 19 } edge[M*2];
 20 int head[N];
 21 int cnt_edge;
 22 
 23 void add_edge(int u, int v)
 24 {
 25     edge[cnt_edge].to = v;
 26     edge[cnt_edge].next = head[u];
 27     head[u] = cnt_edge;
 28     cnt_edge++;
 29 }
 30 vector<int>q;
 31 int dfn[N];
 32 int low[N];
 33 int stk[N];
 34 bool in[N];
 35 int kind[N];
 36 
 37 int top;
 38 int idx;
 39 int cnt;
 40 
 41 int n, m,num;
 42 
 43 void dfs(int u)
 44 {
 45     dfn[u] = low[u] = ++idx;
 46     in[u] = true;
 47     stk[++top] = u;
 48     for (int i = head[u]; i != -1; i = edge[i].next)
 49     {
 50         int v = edge[i].to;
 51         if (!dfn[v])
 52         {
 53             dfs(v);
 54             low[u] = min(low[v], low[u]);
 55         }
 56         else if(in[v])
 57         {
 58             low[u] = min(low[u], dfn[v]);
 59         }
 60     }
 61 
 62     if (low[u] == dfn[u])
 63     {
 64         ++cnt;
 65         int j;
 66         num = 0;
 67         do {
 68             num++;
 69             j = stk[top--];
 70             in[j] = false;
 71             kind[j] = cnt;
 72         } while (j != u);
 73         if(num > 1)
 74         q.push_back(stk[top+1]);
 75     }
 76 }
 77 
 78 void init()
 79 {
 80     memset(dfn, 0, sizeof dfn);
 81     memset(head, -1, sizeof head);
 82     cnt_edge = 0;
 83     top = cnt = idx = 0;
 84 }
 85 int main(){
 86    // freopen("in.txt","r",stdin);
 87     cin>>n;
 88     int a[maxn];
 89     init();
 90     int cnt = 0;
 91     for(int i = 1;i <= n;i++){
 92         scanf("%d",&a[i]);
 93         if(i != a[i]){
 94             add_edge(i,a[i]);
 95         }
 96         else{ q.push_back(i);
 97             cnt = 1;
 98         }
 99     }
100 
101     for(int i = 1;i <= n;i++){
102     if(!dfn[i]){
103         dfs(i);
104     }
105     }
106 
107     if(num == n){
108         cout<<1<<endl;
109         a[q[0]] = q[0];
110         for(int i = 1;i <= n;i++)
111             if(i == n) printf("%d\n",a[i]);
112             else printf("%d ",a[i]);
113     }
114     else{
115         if(cnt)
116             cout<<q.size() - 1<<endl;
117         else
118             cout<<q.size()<<endl;
119         for(int i = 0;i < q.size();i++)
120             a[q[i]] = q[0];
121         for(int i = 1;i <= n;i++){
122             if(i == n) printf("%d\n",a[i]);
123             else printf("%d ",a[i]);
124         }
125     }
126     return 0;
127 }

 

codeforces 698b 图论

标签:

原文地址:http://www.cnblogs.com/shimu/p/5890663.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!