[AHOI2006]上學路線route 最短路+最小割
阿新 • • 發佈:2018-01-15
ron sub 描述 cstring 電腦 編程 ini 自然數 add
輸入文件中第一行有兩個正整數N和M,分別表示合肥市公交車站和公交汽車路線的個數。以下M行,每行(第i行,總第(i+1)行)用四個正整數描述第i條路線:pi, qi, ti, ci;具體含義見上文描述。
1 2 1 3
2 6 1 5
1 3 1 1
3 4 1 1
4 6 1 1
5 6 1 2
1 5 1 4
5
合肥市的公交網絡十分發達,你可以認為任意兩個車站間都可以通過直達或轉車互相到達,當然如果在你提供的刪除方案中,家和學校無法互相到達,那麽則認為上學需要的最短為正無窮大:這顯然是一個合法的方案。
[AHOI2006]上學路線route
Time Limit: 3 Sec Memory Limit: 162 MB
Submit: 2473 Solved: 886
[Submit][Status][Discuss]
Description
可可和卡卡家住合肥市的東郊,每天上學他們都要轉車多次才能到達市區西端的學校。直到有一天他們兩人參加了學校的信息學奧林匹克競賽小組才發現每天上學的乘車路線不一定是最優的。 可可:“很可能我們在上學的路途上浪費了大量的時間,讓我們寫一個程序來計算上學需要的最少時間吧!” 合肥市一共設有N個公交車站,不妨將它們編號為1…N的自然數,並認為可可和卡卡家住在1號汽車站附近,而他們學校在N號汽車站。市內有M條直達汽車路線,執行第i條路線的公交車往返於站點pi和qi之間,從起點到終點需要花費的時間為ti。(1<=i<=M, 1<=pi, qi<=N) 兩個人坐在電腦前,根據上面的信息很快就編程算出了最優的乘車方案。然而可可忽然有了一個鬼點子,他想趁卡卡不備,在卡卡的輸入數據中刪去一些路線,從而讓卡卡的程序得出的答案大於實際的最短時間。而對於每一條路線i事實上都有一個代價ci:刪去路線的ci越大卡卡就越容易發現這個玩笑,可可想知道什麽樣的刪除方案可以達到他的目的而讓被刪除的公交車路線ci之和最小。 [任務] 編寫一個程序: ? 從輸入文件中讀取合肥市公交路線的信息; ? 計算出實際上可可和卡卡上學需要花費的最少時間; ? 幫助可可設計一個方案,刪除輸入信息中的一些公交路線,使得刪除後從家到學校需要的最少時間變大,而被刪除路線的ci和最小;向輸出文件輸出答案。Input
Output
輸出文件最多有兩行。 第一行中僅有一個整數,表示從可可和卡卡家到學校需要的最短時間。 第二行輸出一個整數C,表示Ci之和Sample Input
6 71 2 1 3
2 6 1 5
1 3 1 1
3 4 1 1
4 6 1 1
5 6 1 2
1 5 1 4
Sample Output
25
HINT
2<=N<=500, 1<=M<=124 750, 1<=ti, ci<=10 000
題目大意:給定一張圖,每條邊有一個長度和一個花費,要求刪掉一些邊使1到n的最短路變長,求最小花銷
首先求出最短路(用什麽求隨便,反正數據範圍小),然後將所有在最短路上的邊連到新圖中,求最小割就是答案
1 #include <queue> 2 #include <cstdio> 3 #include <cstring> 4#include <iostream> 5 #include <algorithm> 6 #define N 505 7 #define M 250007 8 #define inf 0x3f3f3f3f 9 using namespace std; 10 struct YYC 11 { 12 int u,v,len,cost,next; 13 }e[M],road[M>>1]; 14 int head[N],cnt; 15 inline void add(int u,int v,int len) 16 { 17 e[++cnt].v=v; 18 e[cnt].len=len; 19 e[cnt].next=head[u]; 20 head[u]=cnt; 21 } 22 int dist[N]; 23 bool in[N]; 24 queue<int>q; 25 void spfa(int s) 26 { 27 while(!q.empty())q.pop(); 28 memset(dist,0x3f,sizeof(dist)); 29 int i,u,v; 30 q.push(s),dist[s]=0,in[s]=1; 31 while(!q.empty()) 32 { 33 u=q.front(),q.pop(),in[u]=0; 34 for(i=head[u];i;i=e[i].next) 35 { 36 v=e[i].v; 37 if(dist[v]>dist[u]+e[i].len) 38 { 39 dist[v]=dist[u]+e[i].len; 40 if(!in[v])q.push(v),in[v]=1; 41 } 42 } 43 } 44 return ; 45 } 46 int s,t,d[N]; 47 bool bfs() 48 { 49 memset(d,0,sizeof(d)); 50 while(!q.empty())q.pop(); 51 int i,u,v; 52 q.push(s); 53 d[s]=1; 54 while(!q.empty()) 55 { 56 u=q.front(),q.pop(); 57 for(i=head[u];i;i=e[i].next) 58 { 59 v=e[i].v; 60 if(!d[v]&&e[i].len) 61 { 62 d[v]=d[u]+1; 63 if(v==t)return 1; 64 q.push(v); 65 } 66 } 67 } 68 return 0; 69 } 70 int dinic(int x,int flow) 71 { 72 if(x==t)return flow; 73 int i,v,remain=flow,k; 74 for(i=head[x];i&&remain;i=e[i].next) 75 { 76 if(d[v=e[i].v]==d[x]+1&&e[i].len) 77 { 78 k=dinic(v,min(remain,e[i].len)); 79 if(!k)d[v]=0; 80 e[i].len-=k,e[i^1].len+=k; 81 remain-=k; 82 } 83 } 84 return flow-remain; 85 } 86 int n,m; 87 int main() 88 { 89 int i,j,k; 90 int a,b,c,d; 91 scanf("%d%d",&n,&m); 92 for(i=1;i<=m;i++) 93 { 94 scanf("%d%d%d%d",&road[i].u,&road[i].v,&road[i].len,&road[i].cost); 95 add(road[i].u,road[i].v,road[i].len); 96 add(road[i].v,road[i].u,road[i].len); 97 } 98 spfa(1); 99 cnt=1; 100 memset(head,0,sizeof(head)); 101 for(i=1;i<=m;i++) 102 { 103 if(dist[road[i].u]+road[i].len==dist[road[i].v])add(road[i].u,road[i].v,road[i].cost),add(road[i].v,road[i].u,0); 104 if(dist[road[i].v]+road[i].len==dist[road[i].u])add(road[i].v,road[i].u,road[i].cost),add(road[i].u,road[i].v,0); 105 } 106 s=1,t=n; 107 int maxflow=0; 108 while(bfs())maxflow+=dinic(s,inf); 109 printf("%d\n%d\n",dist[n],maxflow); 110 }
[AHOI2006]上學路線route 最短路+最小割