《网 络 瘤:从入门到入土》第二卷
\[\huge\color{cornflowerblue}{\texttt{Net flow studying notes: NO.2.}}
\]
\[\large\color{gold}{\texttt{Only Problems Here.}}
\]
\(\tt{P4542}\) 营救皮卡丘
\[\huge\color{darkcyan}{\texttt{1.锂性分析}}
\]
- 对于
经过的点必须按顺序出现(即在经过1~K-1前不能经过K):
我们可以按顺序将点拆分成入点和出点,图中的边即为输入中的入点连向另一端的出点.入点连源点,出点连汇点.
用\(\tt{floyd}\)跑一遍全源最短路,两点间边权即为最短路.
注意编号为0的点与源点的边容量为k.
\[\huge\color{darkcyan}{\texttt{2.感性开打}}
\]
#include <bits/stdc++.h>
#define ri register int
#define MAXN 200001
using namespace std;
const int inf=0x3f3f3f3f;
int n,m,k,s,t,cntr;
int cst,mfl;
int head[MAXN];
int cur[MAXN];
int dist[MAXN];
int gra[2001][2001];
int q[MAXN];
bool vis[MAXN];
inline void floyd()
{
for(ri k=1;k<=n;k++)
for(ri i=1;i<=n;i++)
for(ri j=1;j<=n;j++)
if(k<i||k<j)//注意必须有限制,疯狂WA10次
gra[i][j]=min(gra[i][j],gra[i][k]+gra[k][j]);
}
struct edge{
int to,next,flow,cost;
}e[MAXN];
inline void add(int u,int v,int w,int c)
{
e[cntr].to=v;
e[cntr].flow=w;
e[cntr].cost=c;
e[cntr].next=head[u];
head[u]=cntr++;
}
inline void orz(int u,int v,int w,int c)
{
add(u,v,w,c);
add(v,u,0,-c);
}
inline bool SPFA()
{
memset(dist,inf,sizeof(dist));
memcpy(cur,head,sizeof(head));
dist[s]=0;
vis[s]=1;
int l=0,r=1;
q[++l]=s;
while(l<=r)
{
int u=q[l++];
vis[u]=0;
for(ri i=head[u];~i;i=e[i].next)
{
int v=e[i].to,c=e[i].cost;
if(dist[v]>dist[u]+c&&e[i].flow)
{
dist[v]=dist[u]+c;
if(!vis[v])
vis[v]=1,q[++r]=v;
}
}
}
return dist[t]!=inf;
}
inline int dfs(int now,int maxfl)
{
if(now==t||maxfl==0)
return maxfl;
vis[now]=1;
int tflow=0;
for(ri i=cur[now];~i&&tflow<maxfl;i=e[i].next)
{
cur[now]=i;
int v=e[i].to,c=e[i].cost;
if(!vis[v]&&dist[v]==dist[now]+c&&e[i].flow)
{
int cf=dfs(v,min(maxfl-tflow,e[i].flow));
if(cf)
{
cst+=cf*c;
e[i].flow-=cf;
e[i^1].flow+=cf;
tflow+=cf;
}
}
}
vis[now]=0;
return tflow;
}
inline void SSP()
{
int ad=0;
while(SPFA())
while(ad=dfs(s,inf));
printf("%d",cst);
}
inline int r()
{
int fed=0;
char in=getchar();
bool flag=1;
while(!isdigit(in))
flag&=(in!='-'),in=getchar();
while(isdigit(in))
fed=fed*10+in-'0',in=getchar();
return (2*flag-1)*fed;
}
int main()
{
memset(head,-1,sizeof(head));
n=r(),m=r();
n++;
for(ri i=1;i<=n;i++)
for(ri j=1;j<=n;j++)
{
if(i==j)
continue;
gra[i][j]=inf;
}
k=r();
s=(n<<1)+1,t=(n<<1)+2;
for(ri i=1;i<=m;i++)
{
int a,b,l;
a=r(),b=r();
a++,b++;
l=r();
gra[a][b]=gra[b][a]=min(gra[a][b],l);
}
floyd();
orz(s,1,k,0);
orz(1+t,t,1,0);
for(ri i=2;i<=n;i++)
orz(s,i,1,0),orz(i+t,t,1,0);
for(ri i=1;i<=n;i++)
for(ri j=i+1;j<=n;j++)
if(gra[i][j]!=inf)
orz(i,j+t,inf,gra[i][j]);
SSP();
return 0;
}
\[\texttt{to be continued......}
\]
\[\color{skyblue}{\texttt{And We,}}
\]
\[\color{skyblue}{\texttt{We Burn Faster Than Lights,}}
\]
\[\color{skyblue}{\texttt{Shine Across In The Night Sky,}}
\]
\[\color{skyblue}{\texttt{We Burn Faster Than Lights.}}
\]
\[\color{gold}{◢_◤}
\]

只有一道营救皮卡丘()
浙公网安备 33010602011771号