1877: [SDOI2009]晨跑
Time Limit: 4 Sec Memory Limit: 64 MB
Submit: 1393 Solved: 729
[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
第一次写费用流……
首先拆点,同一个点之间连边,流量为1费用为0(一个点只能走一次)。然后连边跑费用流就好了。
据说还有个zkw费用流?和spfa比哪个快点?
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<algorithm> 6 #include<cmath> 7 #include<vector> 8 #include<queue> 9 #define inf 1000007 10 #define MOD 500 11 using namespace std; 12 int n,m,x,y,z,cnt,ans1,ans2,dis[501],path[501],head[501],q[501]; 13 bool v[501]; 14 int next[100000],from[100000],list[100000],flow[100000],cost[100000]; 15 void insert(int x,int y,int w,int z) 16 { 17 next[++cnt]=head[x]; 18 head[x]=cnt; 19 from[cnt]=x; 20 list[cnt]=y; 21 flow[cnt]=w; 22 cost[cnt]=z; 23 } 24 bool spfa() 25 { 26 int t=0,w=1,x; 27 for (int i=1;i<=2*n;i++) dis[i]=inf; 28 memset(v,0,sizeof(v)); 29 q[1]=1; dis[1]=0; v[1]=1; 30 while (t!=w) 31 { 32 t=(t+1)%MOD; 33 x=q[t]; 34 for (int i=head[x];i;i=next[i]) 35 if (flow[i]>0&&dis[x]+cost[i]<dis[list[i]]) 36 { 37 dis[list[i]]=dis[x]+cost[i]; 38 path[list[i]]=i; 39 if (!v[list[i]]) 40 { 41 v[list[i]]=1; 42 w=(w+1)%MOD; 43 q[w]=list[i]; 44 } 45 } 46 v[x]=0; 47 } 48 return dis[2*n]!=inf; 49 } 50 void mcf() 51 { 52 int x=inf,i; 53 i=path[2*n]; 54 while (i) 55 { 56 x=min(x,flow[i]); 57 i=path[from[i]]; 58 } 59 ans1++; 60 i=path[2*n]; 61 while (i) 62 { 63 ans2+=x*cost[i]; 64 flow[i]-=x; 65 flow[i^1]+=x; 66 i=path[from[i]]; 67 } 68 } 69 int main() 70 { 71 scanf("%d%d",&n,&m); 72 cnt=1; 73 for (int i=1;i<=m;i++) 74 { 75 scanf("%d%d%d",&x,&y,&z); 76 insert(x+n,y,1,z); 77 insert(y,x+n,0,-z); 78 } 79 for (int i=2;i<n;i++) 80 { 81 insert(i,i+n,1,0); 82 insert(i+n,i,0,0); 83 } 84 insert(1,n+1,inf,0); 85 insert(n+1,1,0,0); 86 insert(n,2*n,inf,0); 87 insert(2*n,n,0,0); 88 while (spfa()) mcf(); 89 printf("%d %d",ans1,ans2); 90 return 0; 91 }