IndiaHacks 2016 - Online Edition (Div. 1 + Div. 2) D. Delivery Bears 二分+网络流

来源:互联网 发布:通用工具箱软件 编辑:程序博客网 时间:2024/05/16 17:14

题意:给一个图,每个边有边权,然后有x只熊,每个熊都要背负一样重量的货物,每头熊通过一条路径到i,每条边被所有熊经过的次数乘于货物重量不能大于边权,然后问你最大的货物总重量是多少,每只熊都必须要用,每个熊背负的货物重量一致,所以等价于求每只熊背负的货物的最大重量

思路:二分最大货物总重量,然后跑网络流


#include <cstdio>#include <queue>#include <cstring>#include <iostream>#include <cstdlib>#include <algorithm>#include <vector>#include <map>#include <string>#include <set>#include <ctime>#include <cmath>#include <cctype>using namespace std;#define maxn 600#define INF 1<<29#define LL long longint cas=1,T;struct Edge{int from,to,cap,flow;Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){}};int n,m,x;struct Dinic{//int n,m;    int s,t;vector<Edge>edges;        //边数的两倍vector<int> G[maxn];      //邻接表,G[i][j]表示结点i的第j条边在e数组中的序号bool vis[maxn];           //BFS使用int d[maxn];              //从起点到i的距离int cur[maxn];            //当前弧下标void init(){   for (int i=0;i<=n+2;i++)   G[i].clear();   edges.clear();}void AddEdge(int from,int to,int cap){edges.push_back(Edge(from,to,cap,0));edges.push_back(Edge(to,from,0,0));        //反向弧int mm=edges.size();G[from].push_back(mm-2);G[to].push_back(mm-1);}bool BFS(){memset(vis,0,sizeof(vis));queue<int>q;q.push(s);d[s]=0;vis[s]=1;while (!q.empty()){int x = q.front();q.pop();for (int i = 0;i<G[x].size();i++){Edge &e = edges[G[x][i]];if (!vis[e.to] && e.cap > e.flow){vis[e.to]=1;d[e.to] = d[x]+1;q.push(e.to);}}}return vis[t];}int DFS(int x,int a){if (x==t || a==0)return a;int flow = 0,f;for(int &i=cur[x];i<G[x].size();i++){Edge &e = edges[G[x][i]];if (d[x]+1 == d[e.to] && (f=DFS(e.to,min(a,e.cap-e.flow)))>0){e.flow+=f;edges[G[x][i]^1].flow-=f;flow+=f;a-=f;if (a==0)break;}}return flow;}int Maxflow(int s,int t){this->s=s;this->t=t;int flow = 0;while (BFS()){memset(cur,0,sizeof(cur));flow+=DFS(s,INF);}return flow;}}dc;int u[maxn],v[maxn],c[maxn];bool check(double temp){dc.init();for (int i = 0;i<m;i++){        dc.AddEdge(u[i],v[i],min(c[i]/temp,1.0*x));}dc.AddEdge(0,1,x);dc.AddEdge(n,n+1,x);if (dc.Maxflow(0,n+1)==x)return true;return false;}int main(){//freopen("in","r",stdin);while (scanf("%d%d%d",&n,&m,&x)!=EOF){        for (int i = 0;i<m;i++)scanf("%d%d%d",&u[i],&v[i],&c[i]);    double l=0,r=1e9;double ans=0;        for (int i = 0;i<100;i++){double mid=(l+r)/2;if (check(mid))l=mid,ans=mid;elser=mid;}printf("%.10f\n",ans*x);}//printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC);return 0;}


Description

Niwel is a little golden bear. As everyone knows, bears live in forests, but Niwel got tired of seeing all the trees so he decided to move to the city.

In the city, Niwel took on a job managing bears to deliver goods. The city that he lives in can be represented as a directed graph with nnodes and m edges. Each edge has a weight capacity. A delivery consists of a bear carrying weights with their bear hands on a simple path from node 1 to node n. The total weight that travels across a particular edge must not exceed the weight capacity of that edge.

Niwel has exactlyx bears. In the interest of fairness, no bear can rest, and the weight that each bear carries must be exactly the same. However, each bear may take different paths if they like.

Niwel would like to determine, what is the maximum amount of weight he can deliver (it's the sum of weights carried by bears). Find the maximum weight.

Input

The first line contains three integers nm and x (2 ≤ n ≤ 501 ≤ m ≤ 5001 ≤ x ≤ 100 000) — the number of nodes, the number of directed edges and the number of bears, respectively.

Each of the following m lines contains three integers aibi and ci (1 ≤ ai, bi ≤ nai ≠ bi1 ≤ ci ≤ 1 000 000). This represents a directed edge from node ai to bi with weight capacity ci. There are no self loops and no multiple edges from one city to the other city. More formally, for each i and j that i ≠ j it's guaranteed that ai ≠ aj or bi ≠ bj. It is also guaranteed that there is at least one path from node 1 to node n.

Output

Print one real value on a single line — the maximum amount of weight Niwel can deliver if he uses exactly x bears. Your answer will be considered correct if its absolute or relative error does not exceed 10 - 6.

Namely: let's assume that your answer is a, and the answer of the jury is b. The checker program will consider your answer correct if .

Sample Input

Input
4 4 31 2 22 4 11 3 13 4 2
Output
1.5000000000
Input
5 11 231 2 32 3 43 4 54 5 61 3 42 4 53 5 61 4 22 5 31 5 23 2 30
Output
10.2222222222


0 0
原创粉丝点击