http://acm.hdu.edu.cn/showproblem.php?pid=2448
和那个在地图上回家的差不多~~~
station之间是无向的,port与station是有向的,因为进去就不能出来。
费用流建图,即可
#include <cstring> #include <cstdio> #include <queue> #include <iostream> #define inf 0x3f3f3f3f #define MAXN 3000 #define MAXM 300000 using namespace std; struct node { int u,v,f,c; }; node e[MAXM]; int first[MAXN],next[MAXM],cc; int inq[MAXN],pre[MAXN],preedge[MAXN],d[MAXN]; inline void add_edge(int u,int v,int f,int c) { e[cc].u=u; e[cc].v=v; e[cc].f=f; e[cc].c=c; next[cc]=first[u]; first[u]=cc; cc++; e[cc].v=u; e[cc].u=v; e[cc].f=0; e[cc].c=-c; next[cc]=first[v]; first[v]=cc; cc++; } int SPFA(int s,int t) { memset(inq,0,sizeof(inq)); memset(d,inf,sizeof(d)); memset(pre,-1,sizeof(pre)); memset(preedge,-1,sizeof(preedge)); d[s]=0; queue<int> q; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); inq[u]=0; int i; for(i=first[u];i!=-1;i=next[i]) { int v=e[i].v; if(e[i].f) { if(d[v]>d[u]+e[i].c) { d[v]=d[u]+e[i].c; pre[v]=u; preedge[v]=i; if(!inq[v]) { inq[v]=1; q.push(v); } } } } } if(d[t]>=inf) return 0; else return 1; } int Min_Cost_Flow(int s,int t) { int ans_flow=0,ans_cost=0,mm,tmp; while(SPFA(s,t)) { mm=inf; int u=t; while(pre[u]!=-1) { tmp=preedge[u]; mm=min(mm,e[tmp].f); u=pre[u]; } u=t; while(pre[u]!=-1) { tmp=preedge[u]; e[tmp].f-=mm; e[tmp^1].f+=mm; u=pre[u]; } ans_flow+=mm; ans_cost+=mm*d[t]; } return ans_cost; } int main() { int n,m,k,p; while(scanf("%d%d%d%d",&n,&m,&k,&p)!=EOF) { memset(first,-1,sizeof(first)); memset(next,-1,sizeof(next)); cc=0; int i; int s=0,t=n+m+1; for(i=1;i<=n;i++) { add_edge(i+m,t,1,0); int a; scanf("%d",&a); add_edge(0,a,1,0); } for(i=1;i<=k;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); add_edge(a,b,inf,c); add_edge(b,a,inf,c); } for(i=1;i<=p;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); add_edge(b,a+m,1,c); } int res=Min_Cost_Flow(s,t); printf("%d\n",res); } return 0; }