题意:给出一个有向图,现在让你加最少的边让原图形成强连通图,并输出要加的边。
思路:这题很容易让人联想到缩点,因为题意的原因一定会存在回路,可是试想,缩点之后,可能有很多很多环,然后怎样去处理这么多入度出度都为0的缩点?而且这些缩点是要按照顺序去连接的,否则肯定无法强连通,不仅是这些环,还有不是环的缩点,缩完点之后的处理反而变的很是复杂。所以这题的思路得换!因为这一题一题的原因,我们可以直接dfs去搜索入度为0的点最终的尾巴,还有就是环自身就相当于一个入度为0的点,也得dfs,搜索完了之后我们可以得到很多链式的起点和终点,然后我们要做的就是把这些链按照顺序首尾相连就ok!
#include#include #include #include #include #include #include #include using namespace std;typedef long long ll;int next[100010],rd[100010];int vis[100010];int dfs(int x){ vis[x]=1; if(!vis[next[x]]) return vis[x]=dfs(next[x]); else return vis[x]=x;}vector head,tail;int main (){ memset(vis,0,sizeof(vis)); int n; scanf("%d",&n); for(int i=1; i<=n; i++) { scanf("%d",&next[i]); rd[next[i]]++; } int k=0; for(int i=1; i<=n; i++) if(!rd[i]) { k++; head.push_back(i); tail.push_back(dfs(i)); } int kk=k; for(int i=1; i<=n; i++) if(!vis[i]) { k++; head.push_back(i); tail.push_back(dfs(i)); } if(k==1&&!kk) k=0; printf("%d\n",k); for(int i=0; i