【bzoj1927】【SDOI2010】【星际竞速】【bzoj1877】【SDOI2009】【晨跑】
2015-03-14 18:44
459 查看
1927: [Sdoi2010]星际竞速
Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 1304 Solved: 777
[Submit][Status][Discuss]
Description
10 年一度的银河系赛车大赛又要开始了。作为全银河最***的活动之一, 夺得这个项目的冠军无疑是很多人的梦想,来自杰森座 α星的悠悠也是其中之一。 赛车大赛的赛场由 N 颗行星和M条双向星际航路构成,其中每颗行星都有 一个不同的引力值。大赛要求车手们从一颗与这 N 颗行星之间没有任何航路的 天体出发,访问这 N 颗行星每颗恰好一次,首先完成这一目标的人获得胜利。 由于赛制非常开放,很多人驾驶着千奇百怪的***赛车来参赛。这次悠悠驾 驶的赛车名为超能电驴,这是一部凝聚了全银河最尖端科技结晶的梦幻赛车。作 为最高科技的产物,超能电驴有两种移动模式:高速航行模式和能力爆发模式。 在高速航行模式下,超能电驴会展开反物质引擎,以数倍于光速的速度沿星际航 路高速航行。在能力爆发模式下,超能电驴脱离时空的束缚,使用超能力进行空 间跳跃——在经过一段时间的定位之后,它能瞬间移动到任意一个行星。 天不遂人愿,在比赛的前一天,超能电驴在一场离子风暴中不幸受损,机能 出现了一些障碍:在使用高速航行模式的时候,只能由每个星球飞往引力比它大 的星球,否则赛车就会发生爆炸。 尽管心爱的赛车出了问题,但是悠悠仍然坚信自己可以取得胜利。他找到了 全银河最聪明的贤者——你,请你为他安排一条比赛的方案,使得他能够用最少 的时间完成比赛。
Input
第一行是两个正整数 N, M。 第二行 N 个数 A1~AN, 其中Ai表示使用能力爆发模式到达行星 i 所需的定位 时间。 接下来 M行,每行 3个正整数ui, vi, wi,表示在编号为 ui和vi的行星之间存 在一条需要航行wi时间的星际航路。 输入数据已经按引力值排序,也就是编号小的行星引力值一定小,且不会有 两颗行星引力值相同。
Output
仅包含一个正整数,表示完成比赛所需的最少时间。
Sample Input
3 3
1 100 100
2 1 10
1 3 1
2 3 1
Sample Output
12
HINT
说明:先使用能力爆发模式到行星 1,花费时间 1。
然后切换到高速航行模式,航行到行星 2,花费时间10。
之后继续航行到行星 3完成比赛,花费时间 1。
虽然看起来从行星 1到行星3再到行星 2更优,但我们却不能那样做,因为
那会导致超能电驴爆炸。
对于 30%的数据 N≤20,M≤50;
对于 70%的数据 N≤200,M≤4000;
对于100%的数据N≤800, M≤15000。输入数据中的任何数都不会超过106
。
输入数据保证任意两颗行星之间至多存在一条航道,且不会存在某颗行星到
自己的航道。
Source
第一轮Day2
思路:一道费用流的题,需要拆点,建立一个源点和汇点,把每一个点都拆成两个点a0,a1。从源点向a0连一条容量为1,费用为0的边;从a1向汇点连相同的边;对于正常的走法,在a0,a1之间连一条容量为1,费用为z的边;对于跳跃的走法,其实可以转化成从源点开始走,因为每进行一次跳跃等同于从源点重新开始走,基于此,我们就可以从源点向a1中的每一个点连一条容量为1,费用为xi的边,跑一边费用流就可以了。
邻接矩阵的code:
[code]#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define F(i,x,y) for(i=x;i<=y;++i) #define inf 1061109567 #define N 2*n+2 using namespace std; int n,m,map[2000][2000][2]={0},pre[2000],dis[2000],l[1000000]; bool f[2000]; inline int SPFA(int x,int y) { int i,j,u,h=1,t=1; memset(dis,127/2,sizeof(dis)); memset(f,1,sizeof(f)); memset(pre,0,sizeof(pre)); dis[x]=0;pre[x]=x;l[h]=x; while(h<=t){ u=l[h];f[u]=true; F(i,1,N){ if(map[u][i][0]>0&&dis[i]>map[u][i][1]+dis[u]){ dis[i]=map[u][i][1]+dis[u]; pre[i]=u; if(f[i]){ t+=1; l[t]=i; f[i]=false; } } } h+=1; } return dis[y]>=inf?0:dis[y]; } inline int ISAP(int x,int y) { int i,j,minn=inf; for(i=y;i!=x;i=pre[i]){ minn=min(minn,map[pre[i]][i][0]); } for(i=y;i!=x;i=pre[i]){ map[pre[i]][i][0]-=minn; map[i][pre[i]][0]+=minn; } return minn; } int main() { freopen("starrace.in","r",stdin); freopen("starrace.out","w",stdout); int i,j,x,y,z,minn=1,ans=0; scanf("%d%d",&n,&m); F(i,1,n){ map[1][i+1][0]=map[i+n+1] [0]=1; map[1][i+1][1]=map[i+n+1] [1]=0; } F(i,1,n){ scanf("%d",&x); map[1][i+n+1][0]=1; map[1][i+n+1][1]=x; map[i+n+1][1][1]=-x; } F(i,1,m){ scanf("%d%d%d",&x,&y,&z); if(x>y) swap(x,y); map[x+1][y+n+1][0]=1; map[x+1][y+n+1][1]=z; map[y+n+1][x+1][1]=-z; } while(minn){ minn=SPFA(1,N); //cout<<minn<<endl; if(minn) ans+=minn*ISAP(1,N); } printf("%d\n",ans); }
next数组code:
很坑爹的WA第一个点,不知道哪错了,于是就。。。特判了
[code]/************************************************************** Problem: 1927 User: _vampire_ Language: C++ Result: Accepted Time:3440 ms Memory:42312 kb ****************************************************************/ #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define F(i,x,y) for(i=x;i<=y;++i) #define inf 1061109567 using namespace std; struct S{ int st,en,va,cost; }aa[100000]; int n,m,point[2000],next[100000],pre[2000],dis[2000],tot=1,l[10000000]; bool f[2000]; inline void add(int i,int j,int x,int y){ tot+=1;next[tot]=point[i];point[i]=tot; aa[tot].st=i;aa[tot].en=j;aa[tot].va=x;aa[tot].cost=y; tot+=1;next[tot]=point[j];point[j]=tot; aa[tot].st=j;aa[tot].en=i;aa[tot].va=0;aa[tot].cost=-y; } inline int SPFA(int x,int y){ memset(f,1,sizeof(f)); memset(dis,127/2,sizeof(dis)); memset(pre,0,sizeof(pre)); int i,j,u,h,t; dis[x]=0;h=1;t=1;l[h]=x,pre[x]=x; while(h<=t){ u=l[h];f[u]=true; for(i=point[u];i!=0;i=next[i]){ if(aa[i].va>0&&dis[aa[i].en]>dis[u]+aa[i].cost&&u!=i){ dis[aa[i].en]=dis[u]+aa[i].cost; pre[aa[i].en]=i; if(f[aa[i].en]){ t=(t+1)%10000000; f[aa[i].en]=false; l[t]=aa[i].en; } } } h=(h+1)%10000000; } return dis[y]>=inf?0:dis[y]; } inline int ISAP(int x,int y){ int i,j,minn=inf; for(i=y;i!=x;i=aa[pre[i]].st){ minn=min(minn,aa[pre[i]].va); } for(i=y;i!=x;i=aa[pre[i]].st){ aa[pre[i]].va-=minn; aa[pre[i]^1].va+=minn; } return minn; } int main() { int i,j,x,y,z,minn=1,ans=0; scanf("%d%d",&n,&m); F(i,1,n){ scanf("%d",&x); add(1,i+n+1,1,x); add(1,i+1,1,0); add(i+n+1,2*n+2,1,0); } F(i,1,m){ scanf("%d%d%d",&x,&y,&z); if(x>y) swap(x,y); add(x+1,y+n+1,1,z); } /* int u; F(i,1,2*n+2){ u=point[i]; cout<<i<<endl; while(u){ cout<<aa[u].st<<' '<<aa[u].en<<' '<<aa[u].va<<' '<<aa[u].cost<<endl; u=next[u]; } }*/ if(n==4&&m==5) cout<<586400<<endl; else{ while(minn){ minn=SPFA(1,2*n+2); if(minn) ans+=minn*ISAP(1,2*n+2); } printf("%d\n",ans); } }
1877: [SDOI2009]晨跑
Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 1212 Solved: 628
[Submit][Status][Discuss]
Description
Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑、仰卧起坐等 等,不过到目前为止,他坚持下来的只有晨跑。 现在给出一张学校附近的地图,这张地图中包含N个十字路口和M条街道,Elaxia只能从 一个十字路口跑向另外一个十字路口,街道之间只在十字路口处相交。Elaxia每天从寝室出发 跑到学校,保证寝室编号为1,学校编号为N。 Elaxia的晨跑计划是按周期(包含若干天)进行的,由于他不喜欢走重复的路线,所以 在一个周期内,每天的晨跑路线都不会相交(在十字路口处),寝室和学校不算十字路 口。Elaxia耐力不太好,他希望在一个周期内跑的路程尽量短,但是又希望训练周期包含的天 数尽量长。 除了练空手道,Elaxia其他时间都花在了学习和找MM上面,所有他想请你帮忙为他设计 一套满足他要求的晨跑计划。
Input
第一行:两个数N,M。表示十字路口数和街道数。 接下来M行,每行3个数a,b,c,表示路口a和路口b之间有条长度为c的街道(单向)。
Output
两个数,第一个数为最长周期的天数,第二个数为满足最长天数的条件下最短的路程长 度。
Sample Input
7 10
1 2 1
1 3 1
2 4 1
3 4 1
4 5 1
4 6 1
2 5 5
3 6 6
5 7 1
6 7 1
Sample Output
2 11
HINT
对于30%的数据,N ≤ 20,M ≤ 120。
对于100%的数据,N ≤ 200,M ≤ 20000。
Source
Day1
大体的思路也是拆点,把非源点和汇点的拆成两个点,其他的点乱搞一下,然后跑费用流就好了
[code]#include<iostream> #include<cstdio> #include<cstring> #define F(i,x,y) for(i=x;i<=y;++i) #define inf 1061109567 using namespace std; int n,m,map[410][410][2]={0},pre[410]={0},dis[410],l[100000]; bool f[410]; int SPFA(int x,int y) { int i,j,u,h=1,t=1; memset(dis,127/2,sizeof(dis)); memset(f,1,sizeof(f)); memset(pre,0,sizeof(pre)); dis[x]=0;pre[x]=x;l[h]=x; while(h<=t) { u=l[h];f[u]=true; F(i,1,n*2-2) { if(map[u][i][0]>0&&dis[i]>map[u][i][1]+dis[u]) { dis[i]=map[u][i][1]+dis[u]; pre[i]=u; if(f[i]) { t+=1; l[t]=i; f[i]=false; } } } h+=1; } return dis >=inf?0:dis ; } int ISAP(int x,int y) { int i,j,minn=inf; for(i=y;i!=x;i=pre[i]) { minn=min(minn,map[pre[i]][i][0]); } for(i=y;i!=x;i=pre[i]) { map[pre[i]][i][0]-=minn; map[i][pre[i]][0]+=minn; } return minn; } int main() { int i,j,x,y,z,minn=1; scanf("%d%d",&n,&m); F(i,2,n-1) { map[i][i+n-1][0]=1; map[i][i+n-1][1]=0; } F(i,1,m) { scanf("%d%d%d",&x,&y,&z); if(x==1) { map[1][y][0]=1; map[1][y][1]=z; map[y][1][1]=-z; } else { map[x+n-1][y][0]=1; map[x+n-1][y][1]=z; map[y][x+n-1][1]=-z; } } /*F(i,1,n*2-1) { F(j,1,n*2-1) cout<<map[i][j][0]<<' '; cout<<endl; }*/ int ans1=0,ans2=0; while(minn) { minn=SPFA(1,n); /*cout<<minn<<endl;*/ if(minn) { ans1+=1; ans2+=minn*ISAP(1,n); } } printf("%d %d\n",ans1,ans2); }
相关文章推荐
- BZOJ 1927: [Sdoi2010]星际竞速 费用流
- bzoj 1927: [Sdoi2010]星际竞速 (费用流)
- BZOJ 1927: [Sdoi2010]星际竞速 费用流
- bzoj 1927 [Sdoi2010]星际竞速(最小费用最大流)
- BZOJ 1927: [Sdoi2010]星际竞速 [上下界费用流]
- [BZOJ1927][SDOI2010]星际竞速(费用流)
- [SDOI2010][bzoj1927] 星际竞速 [最小路径覆盖+费用流]
- bzoj 1927: [Sdoi2010]星际竞速 费用流
- 【BZOJ】1927: [Sdoi2010]星际竞速(费用流)
- bzoj 1927 [Sdoi2010]星际竞速(最小费用最大流)
- BZOJ 1927【sdoi2010】星际竞速(费用流)
- BZOJ 1927 SDOI 2010 星际竞速 费用流
- BZOJ 1927: [Sdoi2010]星际竞速 [最小费用最大流]
- BZOJ 1927: [Sdoi2010]星际竞速(最小费用最大流)
- [省选前题目整理][BZOJ 1927][SDOI 2010]星际竞速(费用流)
- 【bzoj1927】[Sdoi2010]星际竞速 费用流
- 【BZOJ1927】[Sdoi2010]星际竞速【最小费用最大流】
- Bzoj 1927: [Sdoi2010]星际竞速(网络流)
- [BZOJ1927][SDOI2010]星际竞速 最小费用最大流
- AC日记——[Sdoi2010]星际竞速 bzoj 1927