求助大佬优化 程序
  • 板块学术版
  • 楼主不慕放糖
  • 当前回复11
  • 已保存回复11
  • 发布时间2021/11/4 21:22
  • 上次更新2023/11/4 01:25:48
查看原帖
求助大佬优化 程序
544113
不慕放糖楼主2021/11/4 21:22
#include<bits/stdc++.h>
using namespace std;
vector<int>e[10000];
vector<int>ef[10000];
vector<int>s;
int vis[10000],color[10000],sccnt;  
vector<int>shortp[10010];
int n,m;//n个点m条边;
struct edge{
	int x,y;
}ed[500000];
void getorder(int u){
    vis[u]=true;
    for(int i=0;i<e[u].size();i++){
        if(!vis[e[u][i]]) getorder(e[u][i]);//将这个点能连接的点依次入栈 
    }
    s.push_back(u);//人栈 
} //getorder遍历的是正图的遍历顺序,按顺序入栈. 
void changecolor(int u) {
  color[u] = sccnt;
  for (int v : ef[u])
    if (!color[v]) changecolor(v);//将这个点能连接到的节点,如果没有颜色就染色
}//changecolor选择最后遍历的节点,将他们成为同一颜色 
void kosaraju() {
  sccnt = 0;//初始化scc的个数为0 
  for (int i = 1; i <= n; ++i)
    if (!vis[i]) getorder(i);//先对正图遍历(按遍历顺序入栈) 
  for (int i = n-1; i >= 0; --i)//s总共只有n个,vector是从0开始的,dfs2从最晚的节点开始选 
    if (!color[s[i]]) {//如果当前节点没有颜色则说明之前相同染色的没有染过他,即是一个新的强连通分量。
      ++sccnt; //联通分量的个数++ 
     changecolor(s[i]);//将这个点变色 
    }
}
int main(){

    cin>>n>>m;
    for(int i=1;i<=m;i++){
        int x,y;
        cin>>x>>y;
        ed[i].x=x;
        ed[i].y=y;
        e[x].push_back(y);//正图;
        ef[y].push_back(x);// 反图; 
    } 
    kosaraju();
   //判断每一条边是不是在同一scc不在就建一条边; 
    for(int i=1;i<=m;i++){
    	if(color[ed[i].x]!=color[ed[i].y]){
    		
    		shortp[ed[i].x].push_back(ed[i].y);
    		
			cout<<ed[i].x <<" "<<ed[i].y<<endl;
		}
	}  
	 
    return 0;
}
/*
6 8
1 3
3 5
5 6
4 6
2 4
1 2
4 1
3 4
*/

kosaraju求缩点 现在有一个问题就是


同一scc的点它不能合并一个点连边,

例如 3连5 5连6 3连6 这是正确的缩点(3 4 5 各代表一个scc)

我的程序会把3连6 改成 4连6(3,4两点是一个scc的)

2021/11/4 21:22
加载中...