bzoj1877

裸的费用流。。拆点就好了

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<ctime>
 6 #include<cstdlib>
 7 #include<algorithm>
 8 #include<vector>
 9 #include<queue>
10 #define rep(i,l,r) for(int i=l;i<(r);i++)
11 #define Rep(i,l,k) rep(i,l,e[k].size())
12 #define clr(a,x) memset(a,x,sizeof(a))
13 typedef long long ll;
14 using namespace std;
15 struct edge{
16     int v,w,c;
17 };
18 struct Ans{
19     int flow,cost;
20 };
21 const int maxn=1009,maxm=100009,inf=0x3fffffff;
22 int s,t,n,m,cnt=0,d[maxn],a[maxn],b[maxn];
23 bool p[maxn];
24 edge E[maxm];
25 vector<int>e[maxn];
26 void addedge(int u,int v,int w,int c){
27     edge ed;
28     ed.v=v;ed.w=w;ed.c=c;
29     e[u].push_back(cnt);E[cnt++]=ed;
30     ed.v=u;ed.w=0;ed.c=-c;
31     e[v].push_back(cnt);E[cnt++]=ed;
32 }
33 bool spfa(){
34     queue<int>Q;
35     clr(p,0);p[s]=1;
36     Q.push(s);
37     rep(i,1,n<<1|1) d[i]=inf;
38     d[s]=0;
39     a[s]=inf;
40     while(!Q.empty()){
41         int x=Q.front();Q.pop();p[x]=0;
42         Rep(i,0,x){
43             edge ed=E[e[x][i]];
44             if(ed.w&&d[ed.v]>d[x]+ed.c){
45                 d[ed.v]=d[x]+ed.c;
46                 a[ed.v]=min(a[x],ed.w);
47                 b[ed.v]=e[x][i];
48                 if(!p[ed.v]){
49                     Q.push(ed.v);
50                     p[ed.v]=1;
51                 }
52             }
53         }
54     }
55     return d[t]!=inf;
56 }
57 Ans costflow(){
58     Ans ans;
59     ans.flow=ans.cost=0;
60     while(spfa()){
61         ans.flow+=a[t];
62         ans.cost+=a[t]*d[t];
63         for(int i=t;i!=s;i=E[b[i]^1].v){
64             E[b[i]].w-=a[t];
65             E[b[i]^1].w+=a[t];
66         }
67     }
68     return ans;
69 }
70 int main(){
71     scanf("%d%d",&n,&m);
72     s=1;t=n;
73     rep(i,2,n<<1|1) if(i!=t) addedge(i,i+n,1,0);
74     rep(i,0,m){
75         int u,v,c;
76         scanf("%d%d%d",&u,&v,&c);
77         addedge(u==1?u:u+n,v,1,c);
78     }
79     Ans ans=costflow();
80     printf("%d %d\n",ans.flow,ans.cost);
81     return 0;
82 }
View Code

1877: [SDOI2009]晨跑

Time Limit: 4 Sec  Memory Limit: 64 MB
Submit: 1446  Solved: 756
[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

[Submit][Status][Discuss]
posted @ 2015-08-30 19:03  ChenThree  阅读(141)  评论(0编辑  收藏  举报