1927: [Sdoi2010]星際競速
Time Limit: 20 Sec Memory Limit: 259 MB
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更優,但我們卻不能那樣做,因
爲那會導致超能電驢爆炸。N≤800,M≤15000。輸入數據中的任何數都不會超過106。輸入數據保證任意兩顆行星
之間至多存在一條航道,且不會存在某顆行星到自己的航道。
Source
第一輪Day2
/*
網絡流.
精妙的建圖.
二元組(c,f).
將每個點i拆成i和i'
由S向i連邊(1,0)
由S向i'連邊(1,w)
由i'向T連邊(1,0)
由u向v'連邊 (i,w)
相當於能量爆發與高速行駛之間的最優抉擇.
分兩種情況
1.由源點流來:指在某一時刻瞬移到該星球
2.由入點流來:指由其他星球沿航路到該星球
*/
#include<iostream>
#include<cstdio>
#include<queue>
#define MAXN 15001
using namespace std;
int n,m,S,T,cut=1,ans,head[MAXN],dis[MAXN],bao[MAXN],fa[MAXN];
struct edge{int u,v,c,f,next;}e[MAXN*20];
bool b[MAXN];
queue<int>q;
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
return x*f;
}
void add(int u,int v,int c,int f)
{
e[++cut].u=u,e[cut].v=v;e[cut].c=c;e[cut].f=f;e[cut].next=head[u];head[u]=cut;
e[++cut].u=u;e[cut].v=v;e[cut].c=0;e[cut].f=-f;e[cut].next=head[u];head[u]=cut;
}
bool bfs(int t)
{
for(int i=0;i<=T;i++) dis[i]=1e7;dis[S]=0;
dis[S]=0;q.push(S);
while(!q.empty())
{
int u=q.front();q.pop();b[u]=false;
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].v;
if(dis[v]>dis[u]+e[i].f&&e[i].c)
{
dis[v]=dis[u]+e[i].f;fa[v]=i;
if(b[v]!=t) b[v]=t,q.push(v);
}
}
}
return dis[T]!=1e7;
}
void mincost()
{
int t=1;
while(bfs(t))
{
int tmp=fa[T],x=1e7;
while(tmp) x=min(x,e[tmp].c),tmp=fa[e[tmp].u];
tmp=fa[T];
while(tmp)
{
e[tmp].c-=x;
e[tmp^1].c+=x;
tmp=fa[e[tmp].u];
}
ans+=dis[T]*x;
t++;
}
}
int main()
{
// freopen("starrace.in","r",stdin);
// freopen("starrace.out","w",stdout);
int x,y,z;
n=read(),m=read();S=0,T=2*n+1;
for(int i=1;i<=n;i++)
{
x=read();
add(S,i,1,0),add(S,i+n,1,x);
add(i,i+n,1,0);
add(i+n,T,1,0);
}
for(int i=1;i<=m;i++)
{
x=read(),y=read(),z=read();
if(x>y) swap(x,y);
add(x,y+n,1,z);
}
mincost();
printf("%d",ans);
return 0;
}