警钟63pts新颖错法,但不知道为啥能过
查看原帖
警钟63pts新颖错法,但不知道为啥能过
452438
_Minecraft12345楼主2024/4/26 18:10

用的dinic+SPFA,这是新的代码,旧的代码看我之前的求助帖

需要注意的是,spfa和dfs共用book数组,spfa结束会刚好清空,spfa开头也会清空一次所以可以共用 只是在dfs里加上了这样一个book数组就过了 不知道会不会是水过的,求大佬指出之前的问题

#include<bits/stdc++.h>
using namespace std;
int head[100010],cur[100010],nxt[100010],to[100010],w[100010];
int cnt=1;
int n,m,s,t;
int c[100010];
void ae(int x,int y,int ww,int cc) {
	++cnt;
	w[cnt]=ww;
	to[cnt]=y;
	nxt[cnt]=head[x];
	head[x]=cnt;
	c[cnt]=cc;
}
int dis[100010];
bool book[100010];
queue<int>q;
bool spfa() {
	memset(dis,0x7f,sizeof(dis));
	//memset(deep,0,sizeof(deep));
	memset(book,0,sizeof(book));
	for(int i=1; i<=n; i++) {
		cur[i]=head[i];
	}
	q.push(s);
	dis[s]=0;
	//deep[s]=1;
	book[s]=1;
	while(!q.empty()) {
		int x=q.front();
		q.pop();
		book[x]=0;
		for(int i=head[x]; i; i=nxt[i]) {
			int y=to[i];
			if(w[i]==0)continue;
			if(dis[y]>dis[x]+c[i]) {
				dis[y]=dis[x]+c[i];
				//deep[y]=deep[x]+1;
				if(book[y]==0) {
					book[y]=1;
					q.push(y);
				}
			}
		}
	}
	//cout<<"wow\n";
	if(dis[t]!=0x7f7f7f7f)return 1;
	return 0;
}

struct node {
	int f,c;//flow,cost
};
node dfs(int x,int minn,int sumcost) {
	if(x==t) {
		return {minn,sumcost*minn};
	}
	book[x]=1;
	for(int &i=cur[x]; i; i=nxt[i]) {
		int y=to[i];
		if(book[y])continue; 
		if(dis[y]!=dis[x]+c[i]||w[i]==0) {
			continue;
		}
		node tmp=dfs(y,min(minn,w[i]),sumcost+c[i]);
		if(tmp.f!=0) {
			w[i]-=tmp.f;
			w[i^1]+=tmp.f;
			//tmp.c+=tmp.f*c[i];
			return tmp;
		}
	}
	return {0,0};
}
int main() {
//	freopen("P3381_8.in","r",stdin);
	cin>>n>>m>>s>>t;
	for(int i=1; i<=m; i++) {
		int ui,vi,wi,ci;
		cin>>ui>>vi>>wi>>ci;
		ae(ui,vi,wi,ci);
		ae(vi,ui,0,-ci);
	}
	int flow=0,cost=0;
	while(spfa()) {
		while(1) {
			node tmp=dfs(s,0x7fffffff,0);
			if(tmp.f==0)break;
			flow+=tmp.f;
			cost+=tmp.c;
		}
	}
	cout<<flow<<' '<<cost;
	return 0;
}
2024/4/26 18:10
加载中...