这个没啥难的. 

只保留可以转移最短路的边,然后拆点跑一个最大流即可.   

#include <bits/stdc++.h>
#define N 1004
#define M 250004
#define ll long long
#define inf 200000000001
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
int s,t,tot,n,m,eds;
int vis[N],current[N],id[N][2],hd[N],to[M],nex[M],val[M],cc[N],U[M],V[M],VAL[M];
void add(int u,int v,int c)
{
    nex[++eds]=hd[u],hd[u]=eds,to[eds]=v,val[eds]=c;
}
struct Dijkstra
{
    ll d[N];
    int done[N];
    struct Node
    {
        int u;
        long long dis;
        Node(int u=0,ll dis=0):u(u),dis(dis){}
        bool operator<(Node b) const
        {
            return b.dis<dis;
        }
    };
    priority_queue<Node>q;
    void dijkstra(int aa)
    {
        memset(d,0x3f,sizeof(d));
        for(d[aa]=0,q.push(Node(aa,0));!q.empty();)
        {
            Node e=q.top();q.pop();
            int u=e.u;
            if(done[u]) continue;
            done[u]=1;
            for(int i=hd[u];i;i=nex[i])
            {
                int v=to[i];
                if(d[v]>d[u]+val[i])
                {
                    d[v]=d[u]+val[i];
                    q.push(Node(v, d[v]));
                }
            }
        }
    }
}S,T;
int d[M];
struct Edge
{
    ll cap;
    int u,v;
    Edge(int u=0,int v=0,ll cap=0):u(u),v(v),cap(cap){}
};
queue<int>q;
vector<Edge>edges;
vector<int>G[N];
void addedge(int u,int v,ll c)
{
    edges.push_back(Edge(u,v,c));
    edges.push_back(Edge(v,u,0));
    int p=edges.size();
    G[u].push_back(p-2);
    G[v].push_back(p-1);
}
int BFS()
{
    memset(vis,0,sizeof(vis));
    d[s]=0,q.push(s),vis[s]=1;
    for(;!q.empty();)
    {
        int u=q.front(); q.pop();
        for(int i=0;i<G[u].size();++i)
        {
            Edge e=edges[G[u][i]];
            if(e.cap>0&&!vis[e.v])
            {
                vis[e.v]=1;
                d[e.v]=d[u]+1;
                q.push(e.v);
            }
        }
    }
    return vis[t];
}
ll dfs(int x,ll cur)
{
    if(x==t) return cur;
    ll f,flow=0;
    for(int i=0;i<G[x].size();++i)
    {
        Edge e=edges[G[x][i]];
        if(e.cap>0 && d[e.v]==d[x]+1)
        {
            f=dfs(e.v,min(cur,1ll*e.cap));
            if(f) flow+=f,cur-=f,edges[G[x][i]].cap-=f,edges[G[x][i]^1].cap+=f;
        }
        if(!cur) break;
    }
    return flow;
}
ll maxflow()
{
    ll flow=0;
    for(;BFS();) flow+=dfs(s,inf);
    return flow;
}
int main()
{
    int i,j,k;
    // setIO("input");
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;++i) id[i][0]=++tot, id[i][1]=++tot;
    for(i=1;i<=m;++i)
    {
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c), add(a,b,c),add(b,a,c);
        U[i]=a,V[i]=b,VAL[i]=c;
    }
    for(i=1;i<=n;++i) scanf("%d",&cc[i]);
    S.dijkstra(1);
    T.dijkstra(n);
    addedge(id[1][0],id[1][1],inf);
    addedge(id[n][0],id[n][1],inf);
    for(i=2;i<n;++i)
    {
        addedge(id[i][0],id[i][1],cc[i]);
    }
    for(i=1;i<=m;++i)
    {
        int a=U[i],b=V[i];
        if(S.d[a]+T.d[b]+VAL[i]==S.d[n])
        {
            addedge(id[a][1],id[b][0],inf);
        }
        swap(a,b);
        if(S.d[a]+T.d[b]+VAL[i]==S.d[n])
        {
            addedge(id[a][1],id[b][0],inf);
        }
    }
    s=id[1][0],t=id[n][1];
    printf("%lld\n",maxflow());
    return 0;
}

  

01-21 20:39