• 2023NOIP A层联测9 紫罗兰


    题目大意

    有一个 n n n个点 m m m边的无向图,一个环的大小为这个环上的点的个数(注意这里的环的大小必须大于等于 3 3 3),求这个图上有多少本质不同的最小环

    1 ≤ n ≤ 3000 , 1 ≤ m ≤ 6000 1\leq n\leq 3000,1\leq m\leq 6000 1n3000,1m6000


    我们考虑对于每条边,求有多少个最小环在这条边上。

    对于每条边,设这条边上的两个点为 x x x y y y,则我们可以在图上删去这条边,然后求 x x x y y y的最短路。因为边权均为 1 1 1,所以用一个 b f s bfs bfs即可 O ( m + n ) O(m+n) O(m+n)求出 x x x到所有点的最短路和最短路的数量。那么,包含这条边的最小环的数量就是点 x x x到点 y y y的最短路的数量,这也就是这条边对答案的贡献。

    将所有贡献加在一起,再除最小环的大小(每个最小环被每条边都算了一次贡献,而环的边数等于环的点数,也就是最小环的大小),即可得到答案。

    时间复杂度为 O ( m 2 + n m ) O(m^2+nm) O(m2+nm)

    code

    #include
    using namespace std;
    int n,m,now=100000,x,y,tot=0,d[20005],l[20005],r[20005],z[20005],dis[3005];
    long long ans=0,v[3005];
    struct vd{
    	int x,y;
    }w[20005];
    queue<int>q;
    void add(int xx,int yy){
    	l[++tot]=r[xx];d[tot]=yy;r[xx]=tot;
    }
    void dd(int v0,int ww){
    	for(int i=1;i<=n;i++){
    		dis[i]=100000;
    		v[i]=0;
    	}
    	dis[v0]=0;
    	v[v0]=1;
    	q.push(v0);
    	while(!q.empty()){
    		int u=q.front();q.pop();
    		for(int i=r[u];i;i=l[i]){
    			if(z[i]) continue;
    			if(dis[u]+1<dis[d[i]]){
    				dis[d[i]]=dis[u]+1;
    				v[d[i]]=v[u];
    				q.push(d[i]);
    			}
    			else if(dis[u]+1==dis[d[i]]){
    				v[d[i]]+=v[u];
    			}
    		}
    	}
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=m;i++){
    		scanf("%d%d",&x,&y);
    		add(x,y);add(y,x);
    		w[i]=(vd){x,y};
    	}
    	for(int i=1;i<=m;i++){
    		x=w[i].x;y=w[i].y;
    		z[i*2-1]=z[i*2]=1;
    		dd(x,y);
    		if(dis[y]<now){
    			now=dis[y];
    			ans=v[y];
    		}
    		else if(dis[y]==now){
    			ans+=v[y];
    		}
    		z[i*2-1]=z[i*2]=0;
    	}
    	printf("%lld",ans/(now+1));
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
  • 相关阅读:
    5分钟教会你如何在生产环境debug代码
    JUC源码学习笔记1——AQS和ReentrantLock
    基于被囊群优化的BP神经网络(分类应用) - 附代码
    简单聊聊Integer
    [LeetCode] 138.复制带随机指针的链表
    Huggingface transformers 里的模型加载的两种方式的写法
    基于Vite+React构建在线Excel
    C++ 学习(八)结构体、结构体数组、结构体指针、结构体嵌套、结构体作为参数、结构体中const使用
    Java8实战-总结47
    JAVA注解总结
  • 原文地址:https://blog.csdn.net/tanjunming2020/article/details/133823218