。。题意说的很清楚了,先求最短路径图再拆点网络流。
居然没被long long坑,1A赞。
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#define inf 1e18
#define ll long long
#define pa pair<ll,int>
using namespace std;
int n,m,cnt,T;
int v[100005],u[100005],w[100005];
int next[500005],list[500005];
int head[1005], cur[1005],q[1005];
ll dis[1005],key[500005];
bool vis[1005];
priority_queue<pa,vector<pa>,greater<pa> > heap;
inline int read()
{
int a=0,f=1; char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
return a*f;
}
inline void insert(int x,int y,ll z)
{
next[++cnt]=head[x];
head[x]=cnt;
list[cnt]=y;
key[cnt]=z;
}
inline void dijkstra()
{
for (int i=1;i<=n;i++) dis[i]=inf;
dis[1]=0;
heap.push(make_pair(0,1));
while (!heap.empty())
{
int x=heap.top().second; heap.pop();
if (vis[x]) continue; vis[x]=1;
for (int i=head[x];i;i=next[i])
if (dis[list[i]]>dis[x]+key[i])
{
dis[list[i]]=dis[x]+key[i];
heap.push(make_pair(dis[list[i]],list[i]));
}
}
}
inline bool BFS()
{
for (int i=1;i<=T;i++) dis[i]=-1;
dis[1]=1; q[1]=1;
int t=0,w=1,x;
while (t<w)
{
x=q[++t];
for (int i=head[x];i;i=next[i])
if (key[i]&&dis[list[i]]==-1)
dis[list[i]]=dis[x]+1,q[++w]=list[i];
}
return dis[T]!=-1;
}
ll find(int x,ll flow)
{
if (x==T) return flow;
ll w,used=0;
for (int i=cur[x];i;i=next[i])
if (key[i]&&dis[list[i]]==dis[x]+1)
{
w=find(list[i],min(key[i],flow-used));
key[i]-=w; key[i^1]+=w; used+=w;
if (used==flow) return used;
}
if (!used) dis[x]=-1;
return used;
}
inline ll dinic()
{
ll tmp=0;
while (BFS())
{
for (int i=1;i<=T;i++) cur[i]=head[i];
tmp+=find(1,inf);
}
return tmp;
}
int main()
{
n=read(); m=read();
for (int i=1;i<=m;i++)
{
u[i]=read(),v[i]=read(),w[i]=read();
insert(u[i],v[i],w[i]); insert(v[i],u[i],w[i]);
}
dijkstra();
cnt=1; T=2*n;
memset(head,0,sizeof(head));
for (int i=1;i<=m;i++)
{
if (dis[u[i]]+w[i]==dis[v[i]])
insert(u[i]+n,v[i],inf),insert(v[i],u[i]+n,0);
if (dis[v[i]]+w[i]==dis[u[i]])
insert(v[i]+n,u[i],inf),insert(u[i],v[i]+n,0);
}
for (int i=1;i<=n;i++)
{
int c=read();
if (i==1||i==n) insert(i,i+n,inf),insert(i+n,i,0);
else insert(i,i+n,c),insert(i+n,i,0);
}
cout << dinic() << endl;
return 0;
}