题解 P4542 【[ZJOI2011]营救皮卡丘】
xtx1092515503 · · 题解
这里是完完全全低人一等的垃圾做法。
首先先说一下自己的思路:因为击败位置
但是发现,我们可以把每个人都留到它击败某层的位置的时候再走。具体而言,在第
代码:
#include<bits/stdc++.h>
using namespace std;
int n,m,p,s,t,tot,DIS[210][210],num[210][210];
namespace MCMF{
const int N=12000;
const int M=7000000;
int head[N],cnt,deg[N],id[N],S,T,dis[N],cost;
struct edge{int to,next,val,cost;}edge[M];
void ae(int u,int v,int w,int c){
// printf("%d %d (%d,%d)\n",u,v,w,c);
edge[cnt].cost=c,edge[cnt].next=head[u],edge[cnt].to=v,edge[cnt].val=w,head[u]=cnt++;
edge[cnt].cost=-c,edge[cnt].next=head[v],edge[cnt].to=u,edge[cnt].val=0,head[v]=cnt++;
}
void ae(int u,int v){deg[u]--,deg[v]++;}
queue<int>q;
bool in[N];
bool SPFA(){
q.push(S),memset(dis,0x3f,sizeof(dis)),dis[S]=0,in[S]=true;
while(!q.empty()){
int x=q.front();q.pop(),in[x]=false;
for(int i=head[x],y;i!=-1;i=edge[i].next)if(edge[i].val&&dis[y=edge[i].to]>dis[x]+edge[i].cost){
dis[y]=dis[x]+edge[i].cost,id[y]=i;
if(!in[y])in[y]=true,q.push(y);
}
}
if(dis[T]==0x3f3f3f3f)return false;
int mn=0x3f3f3f3f;
for(int x=T;x!=S;x=edge[id[x]^1].to)mn=min(mn,edge[id[x]].val);
cost+=mn*dis[T];
for(int x=T;x!=S;x=edge[id[x]^1].to)edge[id[x]].val-=mn,edge[id[x]^1].val+=mn;
return true;
}
}
using namespace MCMF;
int main(){
scanf("%d%d%d",&n,&m,&p),memset(DIS,0x3f,sizeof(DIS)),memset(head,-1,sizeof(head));
for(int i=0;i<=n;i++)DIS[i][i]=0;
for(int i=1,x,y,z;i<=m;i++)scanf("%d%d%d",&x,&y,&z),DIS[x][y]=DIS[y][x]=min(DIS[x][y],z);
for(int i=0;i<=n;i++)for(int j=0;j<=i;j++)num[i][j]=++tot;
s=++tot,t=++tot,S=++tot,T=++tot;
ae(s,num[0][0],p,0);
for(int k=0;k<=n;k++){
for(int i=0;i<=n;i++)for(int j=0;j<=n;j++)DIS[i][j]=min(DIS[i][j],DIS[i][k]+DIS[k][j]);
for(int i=0;i<=k;i++)ae(num[k][i],num[k][k],0x3f3f3f3f,DIS[i][k]),ae(num[k][i],t,0x3f3f3f3f,0);
if(k<n){
for(int i=0;i<=k;i++)ae(num[k][i],num[k+1][i],0x3f3f3f3f,0);
ae(num[k][k],num[k+1][k]);
}
}
ae(num[n][n],t);
ae(t,s,0x3f3f3f3f,0);
for(int i=1;i<=t;i++){
if(deg[i]>0)ae(S,i,deg[i],0);
if(deg[i]<0)ae(i,T,-deg[i],0);
}
while(SPFA());
printf("%d\n",cost);
return 0;
}
然后是正解。正解只需要观察到可以把问题转换成 代码咕了