图论

图论板子

Dijkstra

P4779 【模板】单源最短路径(标准版)

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5,M=2e5+5;
int n,m,s,cnt,hd[N],nxt[M],to[M],w[M],dis[N];
bool vis[N];
struct node{
	int id,d;
	node(int a,int b):id(a),d(b){}
};
bool operator <(node a,node b){
	return a.d>b.d;
}
void add(int a,int b,int c){
	nxt[++cnt]=hd[a];
	hd[a]=cnt;
	to[cnt]=b;
	w[cnt]=c;
}
void dij(int s){
	priority_queue<node>q;
	memset(dis,0x3f,sizeof(dis));
	dis[s]=0;
	q.push(node(s,0));
	while(!q.empty()){
		node p=q.top();
		q.pop();
		if(vis[p.id]) continue;
		vis[p.id]=true;
		for(int i=hd[p.id];i;i=nxt[i]){
			int v=to[i];
			if(p.d+w[i]<dis[v]){
				dis[v]=p.d+w[i];
				q.push(node(v,dis[v]));
			}
		}
	} 
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie();
	cin>>n>>m>>s;
	for(int i=1;i<=m;i++){
		int a,b,c;
		cin>>a>>b>>c;
		add(a,b,c);
	}
	dij(s);
	for(int i=1;i<=n;i++) cout<<dis[i]<<" ";
	return 0;
} 

Spfa

P3385 【模板】负环

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
const int N=2005,M=3005;
int T,n,m,cnt,hd[N],nxt[M<<1],to[M<<1],w[M<<1],dis[N],cnts[N];
bool vis[N];
void add(int a,int b,int c){
	nxt[++cnt]=hd[a];
	hd[a]=cnt;
	to[cnt]=b;
	w[cnt]=c;
}
bool spfa(){
	memset(dis,0x3f,sizeof(dis));
	memset(vis,0,sizeof(vis));
	queue<int>q;
	q.push(1);
	dis[1]=0;
	vis[1]=true;
	while(!q.empty()){
		int u=q.front();
		q.pop();
		vis[u]=false;
		for(int i=hd[u];i;i=nxt[i]){
			int v=to[i];
			if(dis[u]+w[i]<dis[v]){
				dis[v]=dis[u]+w[i];
				if(vis[v]) continue;
				vis[v]=true;
				if(++cnts[v]>n) return true;
				q.push(v);
			}
		}
	}
	return false;
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>T;
	while(T--){
		cnt=0;
		memset(hd,0,sizeof(hd));
        memset(cnts,0,sizeof(cnts));
		cin>>n>>m;
		for(int i=1;i<=m;i++){
			int a,b,c;
			cin>>a>>b>>c;
			add(a,b,c);
			if(c>=0) add(b,a,c);
		}
		if(spfa()) cout<<"YES"<<endl;
		else cout<<"NO"<<endl;
	}
	return 0;
}

Floyd

B3611 【模板】传递闭包

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
const int N=105;
int n,f[N][N];
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			cin>>f[i][j];
		}
	}
	for(int k=1;k<=n;k++){
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				f[i][j]|=f[i][k]&f[k][j];
			}
		} 
	} 
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			cout<<f[i][j]<<" ";
		}
		cout<<endl;
	}
	return 0;
}

差分约束

P5960 【模板】差分约束

#include<bits/stdc++.h>
using namespace std;
const int N=5005;
int n,m,cnt,hd[N],nxt[N<<1],to[N<<1],w[N<<1],dis[N],cnts[N];
bool vis[N];
void add(int a,int b,int c){
	nxt[++cnt]=hd[a];
	hd[a]=cnt;
	to[cnt]=b;
	w[cnt]=c;
} 
void spfa(int s){
	memset(dis,0x3f,sizeof(dis));
	dis[s]=0;
	queue<int>q;
	q.push(s);
	vis[s]=true;
	while(!q.empty()){
		int u=q.front();
		q.pop();
		vis[u]=false;
		for(int i=hd[u];i;i=nxt[i]){
			int v=to[i];
			if(dis[u]+w[i]<dis[v]){
				dis[v]=dis[u]+w[i];
				if(vis[v]) continue;
				vis[v]=true;
				if(++cnts[v]>n+1){
					cout<<"NO";
					exit(0);
				}
				q.push(v);
			}
		} 
	} 
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int a,b,c;
		cin>>a>>b>>c;
		add(b,a,c);
	}
	for(int i=1;i<=n;i++) add(n+1,i,0);
	spfa(n+1);
	for(int i=1;i<=n;i++) cout<<dis[i]<<" ";
	return 0;
}

同余最短路

P3403 跳楼机

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
int cnt,hd[N],nxt[N<<1],to[N<<1];
ll h,x,y,z,w[N<<1],dis[N];
bool vis[N];
struct node{
	int id;
    ll d;
	node(int a,ll b):id(a),d(b){}
};
bool operator <(node a,node b){
	return a.d>b.d;
}
void add(int a,int b,ll c){
	nxt[++cnt]=hd[a];
	hd[a]=cnt;
	to[cnt]=b;
	w[cnt]=c;
}
void dij(){
	priority_queue<node>q;
	memset(dis,0x3f,sizeof(dis));
	dis[0]=0;
	q.push(node(0,0));
	while(!q.empty()){
		node p=q.top();
		q.pop();
		if(vis[p.id]) continue;
		vis[p.id]=true;
		for(int i=hd[p.id];i;i=nxt[i]){
			int v=to[i];
			if(p.d+w[i]<dis[v]){
				dis[v]=p.d+w[i];
				q.push(node(v,dis[v]));
			}
		}
	} 
}
int main(){
	cin>>h>>x>>y>>z;
	h--;
	for(int i=0;i<x;i++){
		add(i,(i+y)%x,y);
		add(i,(i+z)%x,z);
	}
	dij();
	ll ans=0;
	for(int i=0;i<x;i++) if(h>=dis[i])  ans+=(h-dis[i])/x+1;
	cout<<ans;
	return 0;
} 

Toposort

B3644 【模板】拓扑排序 / 家谱树

#include<bits/stdc++.h>
using namespace std;
const int N=105,M=1e4+5;
int n,m,cnt,hd[N],nxt[M],to[M],w[M],d[N];
void add(int a,int b){
	nxt[++cnt]=hd[a];
	hd[a]=cnt;
	to[cnt]=b;
	d[b]++;
}
void Toposort(int s){
	queue<int>q;
	q.push(s);
	while(!q.empty()){
		int u=q.front();
		q.pop();
		if(u!=n+1) cout<<u<<" ";
		for(int i=hd[u];i;i=nxt[i]){
			int v=to[i];
			if(--d[v]==0) q.push(v);
		}
	}
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++){
		int k;
		while(1){
			cin>>k;
			if(!k) break;
			add(i,k);
		}
	}
	int S=n+1;
	for(int i=1;i<=n;i++) if(!d[i]) add(S,i);
	Toposort(S);
	return 0;
}

Kruskal

P3366 【模板】最小生成树

#include<bits/stdc++.h>
using namespace std;
const int N=5005,M=2e5+5;
int n,m,f[N],sz[N];
struct edge{
	int u,v,w;
}e[M];
bool cmp(edge a,edge b){
	return a.w<b.w;
}
int find(int k){
	if(f[k]!=k) f[k]=find(f[k]);
	return f[k];
}
int union1(int a,int b){
	int fa=find(a),fb=find(b);
	if(fa==fb) return -1;
	if(sz[fa]>sz[fb]){
		sz[fa]+=sz[fb];
		f[fb]=fa;
		return sz[fa];
	}
	else{
		sz[fb]+=sz[fa];
		f[fa]=fb;
		return sz[fb];
	}
}
void K(){
	int res=0;
	for(int i=1;i<=n;i++) f[i]=i,sz[i]=1;
	sort(e+1,e+1+m,cmp);
	for(int i=1;i<=m;i++){
		int u=e[i].u,v=e[i].v;
		int z=union1(u,v);
		if(z==-1) continue;
		res+=e[i].w;
		if(z==n){
            cout<<res;
            return;
        }
	}
    cout<<"orz";
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=m;i++) cin>>e[i].u>>e[i].v>>e[i].w;
	K();
	return 0;
}
posted @ 2025-12-18 21:34  czh(抽纸盒)  阅读(2)  评论(0)    收藏  举报