HDU 5988 coding competition

Posted by unclebob on Fri, 20 Dec 2019 19:24:07 +0100

http://acm.hdu.edu.cn/showproblem.php?pid=5988

Title:

Here are n areas, M roads. Next N lines, each line bi,si, each area has bi individuals, si food. Food is immovable. People need to find food along the road, one by one.

Next, line M, vi,ui,ci,pi represent that there is a path between vi and ui. You can walk ci individuals at most. The first one will not damage the path, and the next one will have the probability of pi damage. Ask what is the minimum probability of damage if you find your own food

Analysis:

Minimum damage = 1 - maximum no damage = 1-(1-p1)^k*(1-p2)^k2

1. Build a source point s and a sink point t first

2. After that, the cost of each point and s is 0, the cost of capacity bi and t is 0, and the cost of capacity si is 0

3. The path is to build an edge with capacity of c-1 and cost of - log(1-p) (multiply to add, to change to log(1-p1)+log(1-p2)=log((1-p1)*(1-p2)), because it is a template for the minimum cost, but we want their sum to be as large as possible, so we need to reverse it); at the same time, we need to build a point with capacity of 1 and cost of 0 between them (because we can't walk for the first time) Road damage)

code:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 205;
#define inf 1e9
#define eps 1e-8
struct Edge
{
    int from,to,cap,flow;
	double cost;
	Edge(){}
	Edge(int f,int t,int c,int fl,double co):from(f),to(t),cap(c),flow(fl),cost(co){}
};
struct MCMF
{
    int n,m,s,t;
	vector<Edge>edges;
	vector<int>g[maxn];
	bool inq[maxn];
	double d[maxn];
	int p[maxn];
	int a[maxn];
	void init(int n,int s,int t)
	{
	    this->n=n;
		this->s=s;
		this->t=t;
		edges.clear();
		for(int i = 0;i<=n;i++)g[i].clear();
	}
	void add(int from,int to,int cap,double cost)
	{
	    edges.push_back(Edge(from,to,cap,0,cost));
		edges.push_back(Edge(to,from,0,0,-cost));
		m=edges.size();
		g[from].push_back(m-2);
		g[to].push_back(m-1);
	}
	bool BellmanFord(int &flow,double &cost)
	{
	    for(int i = 0;i<=n;i++)d[i]=inf;
		memset(inq,0,sizeof(inq));
		d[s]=0,a[s]=inf,inq[s]=1,p[s]=0;
		queue<int>q;
		q.push(s);
		while(!q.empty())
		{
		    int u = q.front();
			q.pop();
			inq[u]=0;
			for(int i = 0;i<g[u].size();i++)
			{
			    Edge &e = edges[g[u][i]];
				if(e.cap>e.flow&&d[e.to]>d[u]+e.cost+eps)
				{
				    d[e.to]=d[u]+e.cost;
					p[e.to]=g[u][i];
					a[e.to]=min(a[u],e.cap-e.flow);
					if(!inq[e.to])
					{
					    q.push(e.to);
						inq[e.to]=1;
					}
				}
			}
		}
		if(d[t]==inf)return false;
		flow+=a[t];
		cost+=a[t]*d[t];
		int u = t;
		while(u!=s)
		{
            edges[p[u]].flow+=a[t];
			edges[p[u]^1].flow-=a[t];
			u=edges[p[u]].from;
		}
		return true;
	}
    double work(int &flow,double &cost)
	{
	    flow=0,cost=0;
		while(BellmanFord(flow,cost));
		return cost;
	}
}mm;
int a[maxn],b[maxn];
int main(){
    int Tc,cas=1,S,T,n,m;
    double cst;
     // scanf("%d",&Tc);
      cin>>Tc;
      {
          while(Tc--)
          {
          //scanf("%d%d",&n,&m);
          cin>>n>>m;
          S=0;T=n+1;
          mm.init(n+1,S,T);
          for(int i=1;i<=n;i++)
          {
              cin>>a[i]>>b[i];
              //scanf("%d %d",&a[i],&b[i]);
              int k=min(a[i],b[i]);
              a[i]-=k;b[i]-=k;
              if(a[i]) mm.add(S,i,a[i],0);
              if(b[i]) mm.add(i,T,b[i],0);
          }
          for(int i=1;i<=m;i++)
          {
              int x,y,z;
              double p;
              //scanf("%d%d%d%lf",&x,&y,&z,&p);
              cin>>x>>y>>z>>p;
              p=-log(1-p);
              if(z>0) mm.add(x,y,1,0);
              if(z>1) mm.add(x,y,z-1,p);
          }
          int mf;
          mm.work(mf,cst);
          cst=exp(-cst);
          cst=1.00000-cst;
          cout<<fixed<<setprecision(2)<<cst<<endl;
          }
      }
return 0;
}
/*
999999
4 4
2 0
0 3
3 0
0 3
1 2 5 0.5
3 2 5 0.5
1 4 5 0.5
3 4 5 0.5

4 2
0 3
3 0
0 3
3 0
1 2 5 0.5
3 4 5 0.5

3 2
0 2
1 1
2 0
1 2 2 0.3
2 3 2 0.2

3 3
0 2
1 1
2 0
1 2 2 0.3
2 3 2 0.3
1 3 2 0.3

3 2
1 1
2 0
0 2
1 2 1 0.3
2 3 2 0.7

2 1
4 0
0 4
1 2 4 0.3

*/

 

Topics: PHP