[Template] Differential constraint algorithm

[Template] Differential constraint algorithm

Title:

Insert picture description here

answer:

Explanation of template problem
algorithm
Give a set of m inequalities with n unknowns. Find any set of solutions that satisfy this set of inequalities, or determine that there is no solution.

After connecting the edges, run the shortest path to ensure that each connected block does not have a negative ring.
It is also possible to establish the source point s = 0, s connects 0 edges to all points, which is equivalent to 1 spfa can traverse all connected blocks (note that the negative ring condition cnt[v]>=N+1 at this time).

Code:

Error code (to be revised)

#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof a)
typedef long long ll;
using namespace std;
inline int read(){
    
    
   int s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){
    
    if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);
   return s*w;
}
const int maxn=5e3+9;
struct node{
    
    
	int u,v,w,next;
}edge[maxn];
int head[maxn];
int tot=0;
void add(int u,int v,int w)
{
    
    
	edge[++tot].v=v;
	edge[tot].next=head[u];
	edge[tot].w=w;
	head[u]=tot;
}
int dis[maxn],vis[maxn];
int cnt[maxn];
int n,m;
bool spfa(int now)
{
    
    
	mem(cnt,0);
	mem(vis,0);
	queue<int>q;
	dis[now]=0;
	q.push(now);
	vis[now]=1;
	while(!q.empty())
	{
    
    
		int u=q.front();
		q.pop();
		vis[u]=0;
		for(int i=head[u];i;i=edge[i].next)
		{
    
    
			int v=edge[i].v;
			int w=edge[i].w;
			if(dis[u]+w<dis[v])
			{
    
    
				dis[v]=dis[u]+w;
				cnt[v]=cnt[u]+1;
				if(cnt[v]>=n)return 1;
				if(vis[v]==0)
				{
    
    
					vis[v]=1;
					q.push(v);
				}
			}

		}
	}
	return 0;
}
int main()
{
    
    
	
	cin>>n>>m;
	for(int i=1;i<=n;i++)dis[i]=0x3f;
	for(int i=1;i<=m;i++)
	{
    
    
		int u,v,w;
		cin>>u>>v>>w;
		add(u,v,w);
	}
	for(int i=1;i<=n;i++)
	if(dis[i]==0x3f)
	{
    
    
		if(spfa(i))
		{
    
    
			cout<<"NO"<<endl;
			return 0; 
		}
		for(int i=1;i<=n;i++)
		{
    
    
			cout<<dis[i]<<" ";
		}
		return 0;
	}
	return 0;
}

Correct code:

#include<bits/stdc++.h>
#define MAXN 5005 
#define inf int(16843009)
using namespace std;
int N,M,s,t;
struct edge{
    
    
    int v,w;
    edge(int v=0, int w=0):v(v),w(w){
    
    };
};
vector<edge> adj[MAXN];
int d[MAXN], cnt[MAXN];
bool inq[MAXN];

bool spfa(int s){
    
    
    memset(d, 1, sizeof(d));
    queue<int> q;
    d[s] = 0; q.push(s); inq[s] = 1;

    int u,v,w;
    while(!q.empty()){
    
     
        u = q.front(); q.pop(); inq[u] = 0;
        for(int i=0;i<adj[u].size();i++){
    
    
            v = adj[u][i].v; w = adj[u][i].w;
            if(d[u] + w < d[v]){
    
    
                d[v] = d[u] + w;
                cnt[v] = cnt[u] + 1;//cnt[v] = s->v最短路包含的边数 
                if(cnt[v] >= N+1) return 1;//判负环 
                if(inq[v]==0){
    
    
                    q.push(v); inq[v] = 1;
                }   
            }
        }
    }   
    return 0;
}

int main(){
    
    

    scanf("%d%d", &N, &M);

    int u,v,w;
    for(int i=1;i<=M;i++){
    
    
        scanf("%d%d%d", &v, &u, &w);
        adj[u].push_back(edge(v,w));
    }

    s = 0;
    for(int i=1;i<=N;i++){
    
    
        adj[0].push_back(edge(i,0));
    }

    if(spfa(0)){
    
    
        printf("NO\n");
        return 0;
    }
    for(int i=1;i<=N;i++){
    
    
        printf("%d ", d[i]);
    }
    return 0;
} 

Guess you like

Origin blog.csdn.net/qq_35975367/article/details/115189958