• 判环

    (SPFA)判负环

    亲身试验(dfs)过不了,会被卡成(n^n)。传统(spfa),判断一个点的入队次数,超过(n)就有负环

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    int read(){
    	int x=0;int f=0;char c=getchar();
    	while(c<'0'||c>'9')f|=c=='-',c=getchar();
    	while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return f?-x:x;
    }
    int n,m,T,head[200005],dis[200005],num,q[20000000],h,t,in[200005];
    bool vis[200005],flag;
    struct node{
        int to,next,w;
    }a[400005];
    bool SPFA(){
        memset(dis,0x3f3f3f3f,sizeof(dis));
        memset(vis,0,sizeof(vis));
        memset(in,0,sizeof(in));
        memset(q,0,sizeof(q));
        dis[1]=0,h=t=0;
        q[++t]=1;
        while(h<=t){
        	int u=q[++h];vis[u]=0;
        	if(in[u]>n) return 1;
        	for(int i=head[u],v;v=a[i].to,i;i=a[i].next){
        		if(dis[v]>dis[u]+a[i].w){
        			dis[v]=dis[u]+a[i].w,in[v]=in[u]+1;
        			if(in[v]>n) return 1;
        			if(!vis[v]) q[++t]=v,vis[v]=1;
    			}
    		}
    	}
    	return 0;
    }
    int main(){
        T=read();
        while(T--){
            n=read(),m=read();num=0;
            memset(head,0,sizeof(head));
            for(int x,y,w,i=1;i<=m;i++){
                x=read(),y=read(),w=read();
                a[++num].to=y,a[num].next=head[x],a[num].w=w,head[x]=num;
                if(w>=0) a[++num].to=x,a[num].next=head[y],a[num].w=w,head[y]=num;
            }
            if(SPFA()) printf("YE5
    ");
            else printf("N0
    ");
        }
        return 0;
    }
    

    (Floyed)无向图求最小环

    #include<iostream>
    #include<cstring>
    using namespace std;
    const int inf(0x1f1f1f1f) ;
    int n,m,map[105][105],d[105][105],ans=inf,what[3],p[105][105];
    void print(int x,int y){
    	if(!p[x][y]) cout<<x<<' ';//如果x不能到y,输出x 
    	else print(x,p[x][y]),print(p[x][y],y);
    }
    int main(){
    	scanf("%d%d",&n,&m);
    	memset(map,0x1f,sizeof map);
    	memset(d,0x1f,sizeof d);
    	for(int i=1,x,y,z;i<=m;i++){
    		scanf("%d%d%d",&x,&y,&z);
    		d[x][y]=d[y][x]=map[x][y]=map[y][x]=min(map[y][x],z);//建图 
    	}
    	for(int k=1;k<=n;k++){
    		for(int i=1;i<k;i++)
    			for(int j=i+1;j<k;j++)
    				if(d[i][j]+map[i][k]+map[k][j]<ans){
    					ans=d[i][j]+map[i][k]+map[k][j];//更新最小环的答案 
    					what[0]=k,what[1]=i,what[2]=j;//从i到j中间经过k 
    				}
    		for(int i=1;i<=n;i++)
    			for(int j=1;j<=n;j++)//最短路 
    				if(d[i][j]>d[i][k]+d[k][j])
    					d[i][j]=d[i][k]+d[k][j],p[i][j]=k;//从i到j的最短路经过k
    	}
    	if(ans==inf) cout<<"No solution.";
    	else print(what[1],what[2]),cout<<what[2]<<' '<<what[0];
    	return 0;
    }
    

    欢迎指正评论O(∩_∩)O~~

  • 相关阅读:
    【算法】Manacher算法
    python 02 python入门知识
    python 01:计算机基础知识
    表示数值的字符串
    C++ 迭代器(STL迭代器)iterator详解
    构建乘积数组
    C++ 容器(STL容器)
    数组中重复的数字
    把字符串转换成整数
    十大经典排序算法
  • 原文地址:https://www.cnblogs.com/kylinbalck/p/9879024.html
Copyright © 2020-2023  润新知