codechef Annual Parade
来源:互联网 发布:音箱测试软件 编辑:程序博客网 时间:2024/05/21 09:20
题目大意
一张
对于每组询问.你需要从图中选出若干条路径,相同的边可以经过多次.一个方案的代价是所有经过的道路(多次经过重复统计)的边权和加上起点不等于终点的路径条数乘
对每组询问你需要计算最少代价。
解题思路
注意到
假如只有一个询问的话,我们应该怎么做??!!!
我们好像看到有路径覆盖,还有
考虑如何构图:
将每个点拆为
对于一条原图中的边
我们看一下,假如我们现在从原点增广出了一条新的增广路,他的意义是什么。。。。
1:将两条原本不相交的路径连接在了一起,那么我们就少付了一次非环的钱,
2:连出了一个环,
(其实你可以把一个点想象成一个超短的边。。。。。那么点没有被覆盖其实相当于不是一个环)
我们对于一个
然后我们每次增广出一条增广路对答案的贡献为
因为我们用的是最小费用最大流算法,所以增广出来的
当
我们对于一个询问,我们可以二分出增广到哪一条路,然后最后全部加起来就好了
时间复杂度为
参考代码
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fd(i,a,b) for(int i=a;i>=b;i--)#define maxn 505#define maxm 300005#define mem(a,b) memset(a,b,sizeof(a))#define oo 1e9#define mo 503using namespace std;int head[maxn],t[maxm],next[maxm],v[maxm],cost[maxm],sum;int f[maxn][maxn];int n,m,q;int S,T;int a[maxn],s[maxn];void ins(int x,int y,int z,int co){ t[++sum]=y; v[sum]=z; cost[sum]=co; next[sum]=head[x]; head[x]=sum;}void insert(int x,int y,int z,int co){ ins(x,y,z,co); ins(y,x,0,-co);}int pre[maxn];int dist[maxn];bool bz[maxn];int d[mo+5];bool spfa(){ mem(dist,63); dist[S]=0; int l=0,r=1; d[1]=S; while (l!=r) { l=(l+1) % mo; int now=d[l]; bz[now]=0; for(int tmp=head[now];tmp;tmp=next[tmp]) { if (v[tmp]==0) continue; if (dist[t[tmp]]>dist[now]+cost[tmp]) { dist[t[tmp]]=dist[now]+cost[tmp]; pre[t[tmp]]=tmp; if (!bz[t[tmp]]) { bz[t[tmp]]=1; r=(r+1) % mo; d[r]=t[tmp]; if (dist[d[r]]<dist[d[(l+1) % mo]]) swap(d[r],d[(l+1) % mo]); } } } } return dist[T]<oo / 10;}int main(){ scanf("%d%d%d",&n,&m,&q); S=0; T=n+n+1; sum=1; mem(f,63); fo(i,1,m) { int x,y,z; scanf("%d%d%d",&x,&y,&z); f[x][y]=min(f[x][y],z); } fo(i,1,n) insert(S,i,1,0),insert(i+n,T,1,0),insert(i+n,i,oo,0); fo(i,1,n) fo(j,1,n) { if (f[i][j]>10000) continue; insert(i,j+n,oo,f[i][j]); } while (spfa()){ a[++a[0]]=dist[T]; s[a[0]]=s[a[0]-1]+a[a[0]]; for(int tmp=T;tmp!=S;tmp=t[pre[tmp] ^ 1]) { v[pre[tmp]]--; v[pre[tmp] ^ 1]++; } } while (q--) { int w=0,x; scanf("%d",&x); int l=1,r=a[0]; while (l<=r) { int mid=(l+r) >> 1; if (a[mid]<x) { w=mid; l=mid+1; } else r=mid-1; } printf("%d\n",x*(n-w)+s[w]); } return 0;}
1 0
- codechef Annual Parade
- Parade。。。。
- Parade
- CodeChef
- CodeChef
- CodeChef
- CodeChef
- (CodeChef
- CodeChef
- CodeChef
- CodeChef
- CodeChef
- CodeChef
- CodeChef
- Annual work summary
- B. Parade
- UVALive 4327 Parade(hdu 2490 Parade)
- CodeChef CIELQUIZ
- 初识google多语言通信框架gRPC系列(二)编译gRPC
- PHP判断iPhone、iPad、Android及PC设备
- CoreImage/滤镜的基本使用
- JSP学习笔记
- EhCache实例
- codechef Annual Parade
- mysql_multi管理多实例
- CodeForces 178C3
- 机器学习之逻辑回归和softmax回归及sklearn和tensorflow代码示例
- C语言宏定义的几种简单用法
- Android中常用的设计原则与设计模式
- Nginx搭建负载环境
- Invoking Webservice from PL/SQL (UTL_DBWS&UTL_HTTP)
- 随机数组