震惊,一萌新因为 WA 了一道简单题居然做出了这种事....
查看原帖
震惊,一萌新因为 WA 了一道简单题居然做出了这种事....
602803
_qingshu_楼主2024/1/3 08:39

这标题只是用来吸引您的注意的(笑。

这费用流打一次错一次,T了 5 个点,疑似死循环。

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
int n,m,tot=1,vis[5200010],dis[5200010],cot[520][520];
int top[5200010],pre[5200010];
int head[5200010],ans,s,t;
struct edge{
	int to,nxt,val,spend;
}e[5200010];
inline void add(int u,int v,int val,int spend){
	e[++tot].to=v;
	e[tot].nxt=head[u];
	e[tot].val=val;
	e[tot].spend=spend;
	head[u]=tot;
	
	e[++tot].to=u;
	e[tot].nxt=head[v];
	e[tot].val=0;
	e[tot].spend=-spend;
	head[v]=tot;
}
bool spfa(){
	memset(dis,0x3f,sizeof dis);
	queue<int>q;
	q.push(s);
	dis[s]=0;
	vis[s]=1;
	while(!q.empty()){
		int x=q.front();q.pop();vis[x]=0;
		for(int i=head[x];i;i=e[i].nxt){
			int v=e[i].to;
			if(e[i].val&&dis[v]>dis[x]+e[i].spend){
				dis[v]=dis[x]+e[i].spend;
				if(!vis[v]){
					vis[v]=1;
					q.push(v);
				}
			}
		}
	}
	return (dis[t]!=inf);
}
int dfs(int x,int sum){
	if(x==t)return sum;
	int res=0;vis[x]=1;
	for(int i=head[x];i&&sum;i=e[i].nxt){
		int v=e[i].to;
		if(e[i].val&&!vis[v]&&dis[v]==dis[x]+e[i].spend){
			int k=dfs(v,min(sum,e[i].val));
			e[i].val-=k;
			e[i^1].val+=k;
			sum-=k;
			res+=k;
			ans+=k*e[i].spend;
			pre[x]=v;
		}
	}
	if(!res)dis[x]=inf;
	vis[x]=0;
	return res;
}
void dinic(){
	while(spfa()){
		dfs(s,inf);
		for(int i=1;i<=m;i++){
			if(pre[n+((i-1)*n+top[i])]&&top[i]<n){
				top[i]++;
				int now=n+(i-1)*n+top[i];
				for(int j=1;j<=n;j++){
					add(j,now,1,cot[j][i]*top[i]);
				}
				add(now,t,1,0);
			}
		}
	}
}
signed main(){
	cin>>m>>n;
	s=m*n+n+1;t=s+1;
	for(int i=1;i<=n;i++){
		add(s,i,1,0);
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>cot[i][j];
			add(i,n+(j-1)*n+1,1,cot[i][j]);
		}
	}
	for(int i=1;i<=m;i++){
		top[i]=1;
		add(n+(i-1)*n+1,t,1,0);
	}
	dinic();
	printf("%.2f",(double)ans/(double)n);
}
2024/1/3 08:39
加载中...