题意:不多说了。
题解:
begin
首先想到:我们要强制走过那些下界。
怎么强制呢?我们把费用赋为-inf!!看他走不走!
然后费用的初值就需要把这些扣掉的inf加回来。
end.
贴代码:
#include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 500 #define M 201000 #define inf 2000000 using namespace std; struct KSD { int u,v,w,len,next; }e[M<<3];/*瞎开的大小*/ int head[N],cnt;/*网络流图*/ void add(int u,int v,int w,int len) { ++cnt; e[cnt].u=u,e[cnt].v=v,e[cnt].w=w; e[cnt].len=len,e[cnt].w=w; e[cnt].next=head[u],head[u]=cnt; } int map[N][N];/*预处理的floyd图*/ int n,m,p; int S,s,T; long long dist[N],fee; int pre[N]; bool in[N]; long long spfa() { memset(dist,0x3f,sizeof(dist)); queue<int>q; int i,u,v; dist[S]=0; in[S]=1; q.push(S); while(!q.empty()) { u=q.front();q.pop();in[u]=0; for(i=head[u];i;i=e[i].next) { v=e[i].v; if(!e[i].len)continue; if(dist[v]>dist[u]+e[i].w) { dist[v]=dist[u]+e[i].w; pre[v]=i; if(!in[v]) { in[v]=1; q.push(v); } } } } return dist[T]; } void handle() { for(int i=pre[T];i;i=pre[e[i].u]) { e[i].len-=1; e[i^1].len+=1; } } void build() { int i,j; cnt=1; s=0,S=2*n+1,T=2*n+2; add(S,s,0,p); add(s,S,0,0); add(s,T,0,p); add(T,s,0,0); for(i=1;i<=n;i++) { add(s,i*2-1,map[s][i],1); add(i*2-1,s,-map[s][i],0); add(i*2-1,i*2,-inf,1); add(i*2,i*2-1,inf,0); add(i*2,T,0,1); add(T,i*2,0,0); } for(i=1;i<=n;i++) { for(j=i+1;j<=n;j++) { add(i*2,j*2-1,map[i][j],1); add(j*2-1,i*2,-map[i][j],0); } } } int main() { freopen("B.in","r",stdin); freopen("B.out","w",stdout); int i,j,k; int a,b,c; scanf("%d%d%d",&n,&m,&p); memset(map,0x3f,sizeof(map)); for(i=1;i<=m;i++) { scanf("%d%d%d",&a,&b,&c); map[a][b]=map[b][a]=min(map[a][b],c); } for(i=0;i<=n;i++)map[i][i]=0; for(k=0;k<=n;k++)for(i=0;i<=n;i++)for(j=0;j<=n;j++)if(k<=i||k<=j)map[i][j]=min(map[i][j],map[i][k]+map[k][j]);//floyd build(); fee=inf*n; long long temp; while(temp=spfa(),temp<0x3f3f3f3f3f3f3f3fll) { fee+=temp; handle(); } cout<<fee<<endl; fclose(stdin); fclose(stdout); return 0; }
时间: 2024-10-11 04:48:14