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
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。
【思路】
最小费用最大流
拆个点,两点之间连容量1费用0的边保证每个结点只经过一次。按照给的图连边跑一次最小费用最大流就好了,保证了流量最大的情况下费用最小。
【代码】
1 #include<cmath> 2 #include<queue> 3 #include<vector> 4 #include<cstdio> 5 #include<cstring> 6 #include<iostream> 7 #include<algorithm> 8 #define FOR(a,b,c) for(int a=(b);a<=(c);a++) 9 using namespace std; 10 11 const int N = 500+5; 12 const int INF = 1e9; 13 14 struct Edge { 15 int u,v,cap,flow,cost; 16 }; 17 struct MCMF { 18 queue<int> q; 19 int n,m,a[N],d[N],p[N],inq[N]; 20 vector<Edge> es; vector<int> g[N]; 21 void init(int n) { 22 this->n=n; 23 es.clear(); 24 for(int i=0;i<n;i++) g[i].clear(); 25 } 26 void AddEdge(int u,int v,int cap,int cost) { 27 es.push_back((Edge){u,v,cap,0,cost}); 28 es.push_back((Edge){v,u,0,0,-cost}); 29 int m=es.size(); 30 g[u].push_back(m-2),g[v].push_back(m-1); 31 } 32 bool spfa(int s,int t,int& flow,int& cost) { 33 memset(inq,0,sizeof(inq)); 34 for(int i=0;i<n;i++) d[i]=INF; 35 d[s]=0; inq[s]=1; q.push(s); a[s]=INF; 36 while(!q.empty()) { 37 int u=q.front(); q.pop(); inq[u]=0; 38 for(int i=0;i<g[u].size();i++) { 39 Edge& e=es[g[u][i]]; 40 int v=e.v; 41 if(e.cap>e.flow && d[v]>d[u]+e.cost) { 42 d[v]=d[u]+e.cost; 43 p[v]=g[u][i]; 44 a[v]=min(a[u],e.cap-e.flow); 45 if(!inq[v]) inq[v]=1,q.push(v); 46 } 47 } 48 } 49 if(d[t]==INF) return 0; 50 flow+=a[t]; cost+=a[t]*d[t]; 51 for(int x=t;x!=s;x=es[p[x]].u) 52 es[p[x]].flow+=a[t],es[p[x]^1].flow-=a[t]; 53 return 1; 54 } 55 void mcmf(int s,int t,int& flow,int& cost) { 56 flow=cost=0; 57 while(spfa(s,t,flow,cost)) ; 58 } 59 }mc; 60 61 int n,m; 62 63 int main() { 64 scanf("%d%d",&n,&m); 65 mc.init(n*2+2); 66 int u,v,w,S=1,T=n+n,flow,cost; 67 for(int i=0;i<m;i++) { 68 scanf("%d%d%d",&u,&v,&w); 69 mc.AddEdge(u+n,v,1,w); 70 } 71 for(int i=2;i<=n;i++) 72 mc.AddEdge(i,i+n,1,0); 73 mc.AddEdge(S,1+n,INF,0); 74 mc.AddEdge(n,T,INF,0); 75 mc.mcmf(S,T,flow,cost); 76 printf("%d %d",flow,cost); 77 return 0; 78 }