暑假集训day3
Posted Yzyet
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了暑假集训day3相关的知识,希望对你有一定的参考价值。
今天主要讲的是网络流
涉及到一下2题
Dual Core CPU 和 利润
Dual Core CPU 题目见poj 3469
用最大流做即可
建图很简单不说了
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<queue> using namespace std; inline int read(){ int t=1,num=0; char c=getchar(); while(c>\'9\'||c<\'0\'){if(c==\'-\')t=-1;c=getchar();} while(c>=\'0\'&&c<=\'9\'){num=num*10+c-\'0\';c=getchar();} return num*t; } const int INF=10000010; struct edge{ int to;int c;int rev; }; vector<edge> g[20101]; int n,m,iter[20101],level[20101]; void add(int f,int t,int c){ g[f].push_back((edge){t,c,g[t].size()}); g[t].push_back((edge){f,0,g[f].size()-1}); } void bfs(int s){ memset(level,0,sizeof(level)); queue<int>q; level[s]=1; q.push(s); while(!q.empty()){ int v=q.front();q.pop(); for(int i=0;i<g[v].size();i++){ edge &e=g[v][i]; if(e.c>0&&level[e.to]==0){ level[e.to]=level[v]+1; q.push(e.to); } } } } int dfs(int v,int t,int f){ if(v==t) return f; for(int &i=iter[v];i<g[v].size();i++){ edge &e=g[v][i]; if(e.c>0&&level[v]+1==level[e.to]){ int d=dfs(e.to,t,min(f,e.c)); if(d>0){ e.c-=d; g[e.to][e.rev].c+=d; return d; } } } return 0; } int flow(int s,int t){ int flow=0; while(1){ bfs(s); if(level[t]==0) return flow; memset(iter,0,sizeof(iter)); int f; while((f=dfs(s,t,INF))>0)flow+=f; } } int main() { n=read();m=read(); for(int i=1;i<=n;i++){ int a,b;a=read();b=read(); add(0,i,b);add(i,n+1,a); } for(int i=1;i<=m;i++){ int x,y,w;x=read();y=read();w=read(); add(x,y,w);add(y,x,w); } printf("%d",flow(0,n+1)); return 0; }
利润 题目见9018 1400
本题比较难。。要因为涉及乘法。要把乘法改成加法做最小费用最大流。
调用到cmath库中的exp和log
但是由于exp和log的误差较大,可能在运行的过程中使得某些值为零导致死循环
因此需要调节精度
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> using namespace std; int h[1510],used[1510],que[100010],last[1510]; int k=1,ans1=0;double ans2=0;int n,m,s; double INF=0x7fffff,d[1510]; const double eps=1e-8;//调节精度,见33行 inline int read(){ int t=1,num=0;char c=getchar(); while(c>\'9\'||c<\'0\'){if(c==\'-\')t=-1;c=getchar();} while(c>=\'0\'&&c<=\'9\'){num=(num<<3)+(num<<1)+c-\'0\';c=getchar();} return num*t; } struct edge{ int to;int cap;double cost;int next; }g[40010]; inline void add(int f,int t,int c1,double c2){ g[++k].next=h[f];h[f]=k;g[k].to=t;g[k].cap=c1;g[k].cost=c2; g[++k].next=h[t];h[t]=k;g[k].to=f;g[k].cap=0;g[k].cost=-c2; } bool spfa(int s,int t){ memset(last,0,sizeof(last)); for(int i=1;i<=n;i++)d[i]=INF; memset(used,0,sizeof(used)); int tail,head; head=tail=50002; que[head]=s;used[s]=1;d[s]=0; while(head>=tail){ int x=que[tail++]; for(int i=h[x];i;i=g[i].next){ if(g[i].cap&&d[x]+g[i].cost+eps<d[g[i].to]){ d[g[i].to]=d[x]+g[i].cost; last[g[i].to]=i; if(!used[g[i].to]){ if(d[g[i].to]<d[que[tail]])que[--tail]=g[i].to; else que[++head]=g[i].to; used[g[i].to]=1; } } } used[x]=0; } return d[t]!=INF; } void mcf(int t){ int minn=0x7fffffff;double cnt=0; for(int i=last[t];i;i=last[g[i^1].to])minn=min(minn,g[i].cap); ans1+=minn; for(int i=last[t];i;i=last[g[i^1].to]){ cnt+=g[i].cost; g[i].cap-=minn; g[i^1].cap+=minn; } ans2+=s*exp(cnt)*minn; } int main() { n=read();m=read();s=read(); for(int i=1;i<=m;i++){ int u,v,c,x;u=read();v=read();c=read();x=read(); add(u,v,c,log(1.0+x/100.0)); } while(spfa(1,n))mcf(n); printf("%d\\n%.1lf",ans1,ans2); return 0; }
本文由Yzyet编写,网址为www.cnblogs.com/Yzyet。非Yzyet同意,禁止转载,侵权者必究。
以上是关于暑假集训day3的主要内容,如果未能解决你的问题,请参考以下文章