題目在這裏呀
emm昨天深夜急急地調完這題就睡了,今天補一下題解qaq
這題就是道模板題啦,題意怎麼說的就怎麼建邊,注意需要裂點。
剩下就是一遍網絡流就沒啦ww
這題適合複習一下模板qwq
//Suplex
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#define P pair<int,int>
#define ll long long
#define sec second
#define N 505
#define M 100000+1000
using namespace std;
const ll inf=1e18;
int n,m,head[N+N],cur[N+N],a[M],b[M],d[M],S,T,cnt;
ll dis[N+N];
struct edge{
int to,next;ll cap;
}e[N+N+M+M];
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
inline void add_edge(int u,int v,ll val){
e[++cnt]=(edge){v,head[u],val};head[u]=cnt;
}
void dijkstra()
{
priority_queue<P,vector<P>,greater<P> >q;
for(int i=1;i<=n;i++) dis[i]=inf;
dis[1]=0;q.push(make_pair(0,1));
while(!q.empty()){
int now=q.top().sec;q.pop();
for(int i=head[now];i;i=e[i].next)
if(dis[e[i].to]>dis[now]+e[i].cap){
dis[e[i].to]=dis[now]+e[i].cap;
q.push(make_pair(dis[e[i].to],e[i].to));
}
}
}
bool bfs()
{
queue<int> Q;
for(int i=0;i<=T;i++) dis[i]=-1;
Q.push(S);dis[S]=0;
while(!Q.empty())
{
int now=Q.front();Q.pop();
for(int i=head[now];i;i=e[i].next)
if(e[i].cap && dis[e[i].to]==-1){
dis[e[i].to]=dis[now]+1;
Q.push(e[i].to);
}
}
return dis[T]!=-1;
}
inline ll dfs(int x,ll f)
{
if(x==T) return f;
ll w,used=0;
for(int i=cur[x];i;i=e[i].next)
if(dis[e[i].to]==dis[x]+1){
w=f-used;
w=dfs(e[i].to,min(w,e[i].cap));
e[i].cap-=w;e[i ^ 1].cap+=w;
if(e[i].cap) cur[x]=i;
used+=w;
if(used==f) return f;
}
if(!used) dis[x]=-1;
return used;
}
ll dinic()
{
ll ans=0;
while(bfs()){
for(int i=1;i<=T;i++) cur[i]=head[i];
ans+=dfs(S,inf);
}
return ans;
}
int main()
{
n=read();m=read();
for(int i=1;i<=m;i++){
a[i]=read();b[i]=read();d[i]=read();
add_edge(a[i],b[i],d[i]);add_edge(b[i],a[i],d[i]);
}
dijkstra();
memset(head,0,sizeof(head));
cnt=1;
for(int i=1;i<=m;i++){
if(dis[a[i]]+d[i]==dis[b[i]]) add_edge(a[i]+n,b[i],inf),add_edge(b[i],a[i]+n,0);
if(dis[b[i]]+d[i]==dis[a[i]]) add_edge(b[i]+n,a[i],inf),add_edge(a[i],b[i]+n,0);
}
for(int i=1;i<=n;i++){
int c=read();
if(i>1 && i<n) add_edge(i,i+n,c);
else add_edge(i,i+n,inf);
add_edge(i+n,i,0);
}
S=1;T=n+n;
printf("%lld\n",dinic());
return 0;
}
/*
7 10
1 2 2
1 5 2
2 4 1
2 3 3
3 7 1
4 5 4
4 3 1
4 6 1
5 6 2
6 7 1
1
100
20
50
20
60
1
*/