生活随笔
收集整理的這篇文章主要介紹了
1266: [AHOI2006]上学路线route
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 1266: [AHOI2006]上學路線route
Description
可可和卡卡家住合肥市的東郊,每天上學他們都要轉車多次才能到達市區西端的學校。直到有一天他們兩人參加了學校的信息學奧林匹克競賽小組才發現每天上學的乘車路線不一定是最優的。 可可:“很可能我們在上學的路途上浪費了大量的時間,讓我們寫一個程序來計算上學需要的最少時間吧!” 合肥市一共設有N個公交車站,不妨將它們編號為1…N的自然數,并認為可可和卡卡家住在1號汽車站附近,而他們學校在N號汽車站。市內有M條直達汽車路線,執行第i條路線的公交車往返于站點pi和qi之間,從起點到終點需要花費的時間為ti。(1<=i<=M, 1<=pi, qi<=N) 兩個人坐在電腦前,根據上面的信息很快就編程算出了最優的乘車方案。然而可可忽然有了一個鬼點子,他想趁卡卡不備,在卡卡的輸入數據中刪去一些路線,從而讓卡卡的程序得出的答案大于實際的最短時間。而對于每一條路線i事實上都有一個代價ci:刪去路線的ci越大卡卡就越容易發現這個玩笑,可可想知道什么樣的刪除方案可以達到他的目的而讓被刪除的公交車路線ci之和最小。 [任務] 編寫一個程序: ? 從輸入文件中讀取合肥市公交路線的信息; 計算出實際上可可和卡卡上學需要花費的最少時間; ?幫助可可設計一個方案,刪除輸入信息中的一些公交路線,使得刪除后從家到學校需要的最少時間變大,而被刪除路線的ci和最小;向輸出文件輸出答案。
Input
輸入文件中第一行有兩個正整數N和M,分別表示合肥市公交車站和公交汽車路線的個數。以下M行,每行(第i行,總第(i+1)行)用四個正整數描述第i條路線:pi, qi, ti, ci;具體含義見上文描述。
Output
輸出文件最多有兩行。 第一行中僅有一個整數,表示從可可和卡卡家到學校需要的最短時間。 第二行輸出一個整數C,表示Ci之和
Sample Input
6 7
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
Sample Output
2
5
HINT
2<=N<=500, 1<=M<=124 750, 1<=ti, ci<=10 000
合肥市的公交網絡十分發達,你可以認為任意兩個車站間都可以通過直達或轉車互相到達,當然如果在你提供的刪除方案中,家和學校無法互相到達,那么則認為上學需要的最短為正無窮大:這顯然是一個合法的方案。
這個提示我并沒有發現他有什么用 可能是我太弱了? 顯然 可可要刪除一些邊 不讓卡卡走最短路(心機)? 于是我第一遍就跑A* 找所有最短路 統計切斷所有最短路的代價之和 結果只有30分 我真是蠢啊 切斷所有最短路的代價和 不就是最小割嘛? 把所有最短路分離出來 構成一個新圖 跑最大流dinic? 1 #include <queue>
2 #include <cstdio>
3 #include <cctype>
4 #include <cstring>
5
6 const int MAXN=
510;
7 const int INF=
0x3f3f3f3f;
8
9 int n,m;
10
11 int f[MAXN][MAXN],dep[MAXN<<
1],cur[MAXN<<
1];
12
13 struct node {
14 int x,y;
15 int val;
16 int fee;
17 };
18 node e[MAXN*
MAXN];
19
20 struct edge {
21 int to;
22 int val;
23 int next;
24 edge() {}
25 edge(
int to,
int val,
int next):to(to),val(val),next(next){}
26 };
27 edge Edge[MAXN*MAXN*
10];
28
29 int head[MAXN<<
1],tot=
1;
30
31 inline
void read(
int&
x) {
32 int f=
1;register
char c=
getchar();
33 for(x=
0;!isdigit(c);c==
'-'&&(f=-
1),c=
getchar());
34 for(;isdigit(c);x=x*
10+c-
48,c=
getchar());
35 x=x*
f;
36 }
37
38 inline
void add(
int x,
int y,
int val) {
39 Edge[++tot]=
edge(y,val,head[x]);
40 head[x]=
tot;
41 Edge[++tot]=edge(x,
0,head[y]);
42 head[y]=
tot;
43 }
44
45 inline
int min(
int a,
int b) {
return a<b?
a:b;}
46
47 inline
bool bfs() {
48 std::queue<
int>
q;
49 for(
int i=
1;i<=n;++i) cur[i]=head[i],dep[i]=-
1;
50 q.push(
1);dep[
1]=
0;
51 while(!
q.empty()) {
52 int u=
q.front();
53 q.pop();
54 for(
int i=head[u];i;i=
Edge[i].next) {
55 int v=
Edge[i].to;
56 if(Edge[i].val&&dep[v]==-
1) {
57 dep[v]=dep[u]+
1;
58 q.push(v);
59 if(v==n)
return true;
60 }
61 }
62 }
63 return false;
64 }
65
66 int dfs(
int u,
int flow) {
67 if(u==n)
return flow;
68 int delat,used=
0;
69 for(
int&i=cur[u];i;i=
Edge[i].next) {
70 int v=
Edge[i].to;
71 if(dep[v]==dep[u]+
1&&
Edge[i].val) {
72 delat=dfs(v,min(Edge[i].val,flow-
used));
73 if(delat) {
74 Edge[i].val-=
delat;
75 Edge[i^
1].val+=
delat;
76 used+=
delat;
77 if(used==flow)
break;
78 }
79 }
80 }
81 if(used!=flow) dep[u]=-
1;
82 return used;
83 }
84
85 inline
void dinic() {
86 int ans=
0;
87 while(bfs()) ans+=dfs(
1,INF);
88 printf(
"%d\n",ans);
89 return;
90 }
91
92 int hh() {
93 read(n);read(m);
94 memset(f,
63,
sizeof f);
95 for(
int i=
1;i<=n;++i) f[i][i]=
0;
96 for(
int x,y,z,k,i=
1;i<=m;++
i) {
97 read(e[i].x);read(e[i].y);read(e[i].val);read(e[i].fee);
98 f[e[i].x][e[i].y]=
min(e[i].val,f[e[i].x][e[i].y]);
99 f[e[i].y][e[i].x]=
f[e[i].x][e[i].y];
100 }
101 for(
int k=
1;k<=n;++
k)
102 for(
int i=
1;i<=n;++
i)
103 for(
int j=
1;j<=n;++
j)
104 f[i][j]=min(f[i][j],f[i][k]+
f[k][j]);
105 printf(
"%d\n",f[
1][n]);
106 for(
int i=
1;i<=m;++
i) {
107 int x=e[i].x,y=
e[i].y;
108 if(f[
1][x]+e[i].val+f[y][n]==f[
1][n])
109 add(x,y,e[i].fee);
110 if(f[
1][y]+e[i].val+f[x][n]==f[
1][n])
111 add(y,x,e[i].fee);
112 }
113 dinic();
114 return 0;
115 }
116
117 int sb=
hh();
118 int main(
int argc,
char**argv) {;}
代碼 ?
轉載于:https://www.cnblogs.com/whistle13326/p/7491964.html
總結
以上是生活随笔為你收集整理的1266: [AHOI2006]上学路线route的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。