Codeforces Beta Round #22 (Div. 2 Only) E. Scheme dfs贪心

E. Scheme
 

To learn as soon as possible the latest news about their favourite fundamentally new operating system, BolgenOS community from Nizhni Tagil decided to develop a scheme. According to this scheme a community member, who is the first to learn the news, calls some other member, the latter, in his turn, calls some third member, and so on; i.e. a person with index i got a person with index fi, to whom he has to call, if he learns the news. With time BolgenOS community members understood that their scheme doesn't work sometimes — there were cases when some members didn't learn the news at all. Now they want to supplement the scheme: they add into the scheme some instructions of type (xi, yi), which mean that person xi has to call person yi as well. What is the minimum amount of instructions that they need to add so, that at the end everyone learns the news, no matter who is the first to learn it?

Input

The first input line contains number n (2 ≤ n ≤ 105) — amount of BolgenOS community members. The second line contains n space-separated integer numbers fi (1 ≤ fi ≤ n, i ≠ fi) — index of a person, to whom calls a person with index i.

Output

In the first line output one number — the minimum amount of instructions to add. Then output one of the possible variants to add these instructions into the scheme, one instruction in each line. If the solution is not unique, output any.

Examples
input
3
3 3 2
output
1
3 1

 

题意:

  给出n个节点,以及和这个节点指向的节点fi,表示从i能够到达fi,问至少需要添加多少条边能够使得原图变为强连通分量,

  输出边数及添加的边,多解输出任意一组解。

题解:

  根据题意,每个点出发都可以到达一个强连通分量

  那么起始点我们选取入度为0的就行,那么它可以到达一个环上的点,有多个独立的这样链的形式

  最少的边使它们强连通,那么就是首尾相连了,注意还有就是独立的环,我们也要作出一条链来

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair
typedef long long LL;
const long long INF = 1e18+1LL;
const double Pi = acos(-1.0);
const int N = 1e5+10, M = 1e3+20, mod = 1e9+7,inf = 2e9;

int vis[N],call[N],recall[N],called[N],asd[N],n,callin[N],callout[N];
void dfs(int u) {
    vis[u] = 1;
    if(!vis[call[u]]) dfs(call[u]);
    asd[u] = asd[call[u]];
    if(asd[u] == 0) asd[u] = u;
}
int main() {
    scanf("%d",&n);
    for(int i = 1; i <= n; ++i) {
        scanf("%d",&call[i]);
        called[call[i]] = 1;
    }
    for(int i = 1; i <= n; ++i)
        if(!vis[i]) dfs(i);
    int top = 0,top2 = 0;
    for(int i = 1; i <= n; ++i) {
        if(!called[i]) {
            callin[++top] = i;
            callout[top] = asd[i];
            recall[asd[i]] = 1;
        }
    }
    top2 = top;
    for(int i = 1; i <= n; ++i) {
        if(asd[i] == i && !recall[i]) {
            ++top;
            callin[top] = callout[top] = i;
        }
    }
    if(top2 == 0 && top == 1) top = 0;
    printf("%d\n",top);
    for(int i = 1; i <= top; ++i)
        printf("%d %d\n",callout[i],callin[i%top+1]);
    return 0;
}

 

posted @ 2017-06-15 11:13  meekyan  阅读(264)  评论(0编辑  收藏  举报