最大权闭合图(Road constructions)hdu3917
题意:给出n个城市,k条道路,每条道路都有其负责的公司和花费,m个公司来投标修路,给出m个公司承包需要交纳的赋税,如果第i个公司负责修1-->2路,第j个公司负责修2-->3路,如果选择了第i个公司则必须选择第j个公司来修理后继的工程,问国家在的最大收入最大是多少?
分析:首先处理出来每个公司的后继公司,之间建边,然后源点s与正权收入的建边,负权收入的公司与汇点t建边,公司于公司之间建边,容量inf
#include"stdio.h" #include"string.h" #include"stdlib.h" #include"algorithm" #include"math.h" #include"vector" #include"queue" #include"map" #include"string" #define Maxn 6009 #define Maxm 3000*3000 #define inf 1000000000000000LL #define eps 1e-7 #define pps 1e-18 #define PI acos(-1.0) #define LL __int64 using namespace std; struct node { int u,v,next; LL w; }edge[Maxm]; int t,head[Maxn],work[Maxn],dis[Maxn]; LL cost[Maxn],tax[Maxn]; LL min(LL a,LL b) { return a<b?a:b; } void init() { t=0; memset(head,-1,sizeof(head)); } void add(int u,int v,LL w) { edge[t].u=u; edge[t].v=v; edge[t].w=w; edge[t].next=head[u]; head[u]=t++; edge[t].u=v; edge[t].v=u; edge[t].w=0; edge[t].next=head[v]; head[v]=t++; } int bfs(int S,int T) { queue<int>q; memset(dis,-1,sizeof(dis)); q.push(S); dis[S]=0; while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(edge[i].w&&dis[v]==-1) { dis[v]=dis[u]+1; if(v==T) return 1; q.push(v); } } } return 0; } LL dfs(int cur,LL a,int T) { if(cur==T)return a; for(int &i=work[cur];~i;i=edge[i].next) { int v=edge[i].v; if(edge[i].w&&dis[v]==dis[cur]+1) { LL tt=dfs(v,min(a,edge[i].w),T); if(tt) { edge[i].w-=tt; edge[i^1].w+=tt; return tt; } } } return 0; } LL Dinic(int S,int T) { LL ans=0; while(bfs(S,T)) { memcpy(work,head,sizeof(head)); while(LL tt=dfs(S,inf,T)) ans+=tt; } return ans; } struct st { int u,v,id; LL cost; }e[3009]; struct Edge { int id; Edge(int iid) { id=iid; } }; vector<Edge>s[1009]; int main() { int n,m,i,k,j; while(scanf("%d%d",&n,&m),n||m) { for(i=1;i<=m;i++) scanf("%I64d",&tax[i]); scanf("%d",&k); for(i=1;i<=n;i++) s[i].clear(); map<int,int>mp[6009]; memset(cost,0,sizeof(cost)); for(i=1;i<=k;i++) { scanf("%d%d%d%I64d",&e[i].u,&e[i].v,&e[i].id,&e[i].cost); s[e[i].u].push_back(i); cost[e[i].id]+=e[i].cost; } init(); for(i=1;i<=k;i++) { for(j=0;j<(int)s[e[i].v].size();j++) { int ii=s[e[i].v][j].id; if(e[i].id==e[ii].id)continue; if(!mp[e[i].id][e[ii].id]) { mp[e[i].id][e[ii].id]=1; add(e[i].id,e[ii].id,inf); } } } LL sum=0; for(i=1;i<=m;i++) { if(tax[i]-cost[i]>0) { add(0,i,tax[i]-cost[i]); sum+=tax[i]-cost[i]; } else if(tax[i]-cost[i]<0) add(i,m+1,cost[i]-tax[i]); } LL ans=Dinic(0,m+1); printf("%I64d\n",sum-ans); } return 0; }