The question is to ship K goods to point N from point 1 .. maximum capacity and unit fee per edge... the cost of one route is calculated as a * x ^ 2 .. a is the unit fee for road change .. x indicates the carrying cargo weight... ask about the minimum cost of shipping K items .. obviously, the minimum fee is the maximum stream... but it's not bare .. because a * x ^ 2 is not a linear relationship... an error occurred while running the template directly .. for example, the third group of data in the sample .... so in order to make the maximum flow of the minimum cost .. we need to find a way to convert the relationship between flow and unit fee to linear... for any positive integer x ^ 2 = 1 + 3 + 5 + .. (2 * x-1 ).... then a * x ^ 2 can be equivalent to a * (1 * x + 3 * x + 5 * x +... (2 * x-1) * x) = (1 * a + 3 * a + 5 * a +... (2 * x-1) * a) * x = 1 * (a * x) + 3 * (a * x) + 5 * (a * x) + .. (2 * x-1) * (a * x ).. while a * x is linearly related .... in addition, the data range shows that the C value of each vertex is 5 at most, that is, the split edge can be split into 5 at most... so you can split it... for example, if an edge is (s = 1, e = 2, a = 2, c = 4), it is split into four sides: (s = 1, e = 2, a = 2*1, c = 1) (s = 1, e = 2, a = 2*3, c = 1) (s = 1, e = 2, a = 2 * 5c = 1) (s = 1, e = 2, a = 2*7, c = 1) Program:
#include<iostream>#include<string.h>#include<algorithm>#include<cmath>#include<queue>#include<stdio.h>#include<stack>#define oo 1000000007#define ll long long#define pi acos(-1.0)using namespace std;struct node{ int x,y,c,a,next; }line[100005];int N,M,K,flow,cost,_next[125],pre[125],dis[125]; queue<int> myqueue;bool inqueue[125];void addline(int x,int y,int num,int a,int c){ line[num].next=_next[x],_next[x]=num; line[num].x=x,line[num].y=y,line[num].a=a,line[num].c=c; return;}bool SPFA(){ int x,k; while (!myqueue.empty()) myqueue.pop(); memset(pre,0,sizeof(pre)); memset(dis,0x7f,sizeof(dis)); memset(inqueue,false,sizeof(inqueue)); myqueue.push(1); dis[1]=0; while (!myqueue.empty()) { x=myqueue.front(); myqueue.pop(); inqueue[x]=false; k=_next[x]; while (k) { if (line[k].c && dis[line[k].y]>dis[x]+line[k].a) { dis[line[k].y]=dis[x]+line[k].a; pre[line[k].y]=k; if (!inqueue[line[k].y]) { inqueue[line[k].y]=true; myqueue.push(line[k].y); } } k=line[k].next; } } if (dis[N]>oo) return false; cost=dis[N],flow=oo; x=pre[N]; while (x) { flow=min(flow,line[x].c); x=pre[line[x].x]; } x=pre[N]; while (x) { line[x].c-=flow; if (x%2) line[x+1].c+=flow; else line[x-1].c+=flow; x=pre[line[x].x]; } return true; }int MinCost_MaxFlow(){ int i,MaxFlow=0,MinCost=0; while (MaxFlow<K && SPFA()) { MaxFlow+=flow; MinCost+=cost*flow; } if (MaxFlow<K) return -1; return MinCost;}int main(){ int x,y,a,c,num,i; freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); while (~scanf("%d%d%d",&N,&M,&K)) { memset(_next,0,sizeof(_next)); num=0; while (M--) { scanf("%d%d%d%d",&x,&y,&a,&c); for (i=1;i<=c;i++) addline(x,y,++num,a*(i*2-1),1),addline(y,x,++num,a*(1-i*2),0); } printf("%d\n",MinCost_MaxFlow()); } return 0;}