求的是最多的天数,和这些天跑步总路程最小.
我们将每两个点之间看成流量为一的通道,那么从源点到汇点,最大的流量就是从寝室跑到学校最多的路线,即最多天数.
并且题目里要求每个点只经过一次,那么需要将每一个点拆分成两个点,之间的边流量设置成一,这样就会保证只有一条路通过这个点了.剩下的就是套模板了...
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<string.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
const int maxn=500;
int dis[maxn];
int vis[maxn];
int pre[maxn];
int fflow,ccost;
struct Lu
{
int to;
int flow;
int cost;
Lu(int to=0,int flow=0,int cost=0):to(to),flow(flow),cost(cost) {}
};
vector<Lu>E;
vector<int>V[maxn];
int spfa(int s,int t)
{
for(int i=s; i<=t; i++)
{
pre[i]=-1;
vis[i]=0;
dis[i]=inf;
}
queue<int>Q;
dis[s]=0;
vis[s]=1;
Q.push(s);
int top,vlen;
Lu L;
while(!Q.empty())
{
top=Q.front();
Q.pop();
vis[top]=0;
vlen=V[top].size();
for(int i=0; i<vlen; i++)
{
L=E[V[top][i]];
if(L.flow>0&&dis[L.to]>dis[top]+L.cost)
{
dis[L.to]=dis[top]+L.cost;
pre[L.to]=V[top][i];//记得是边标号,不是前驱点
if(!vis[L.to])
{
Q.push(L.to);
vis[L.to]=1;
}
}
}
}
if(dis[t]==inf)return 0;
return 1;
}
void MinCostMaxFlow(int s,int t)//模板
{
fflow=0;
ccost=0;
int minl=inf;
while(spfa(s,t))
{
minl=inf;
for(int i=pre[t]; i!=-1; i=pre[E[i^1].to])
{
minl=min(minl,E[i].flow);
}
fflow+=minl;
for(int i=pre[t]; i!=-1; i=pre[E[i^1].to])
{
E[i].flow-=minl;
E[i^1].flow+=minl;
ccost+=minl*E[i].cost;
//cout<<ccost<<endl;
}
}
return ;
}
int main()
{
int n,m,a,b,c;
while(~scanf("%d%d",&n,&m))
{
for(int i=0; i<=2*n+2; i++)V[i].clear();
E.clear();
E.push_back(Lu(1+n,inf,0));//源点可以经过很多次,那么拆分成之后相连的边容量设成无限大
E.push_back(Lu(1,0,0));//反向弧
V[1+n].push_back(E.size()-1);
V[1].push_back(E.size()-2);
for(int i=2; i<=n; i++)
{
E.push_back(Lu(i+n,1,0));
E.push_back(Lu(i,0,0));
V[i+n].push_back(E.size()-1);
V[i].push_back(E.size()-2);
}
for(int i=1; i<=m; i++)
{
scanf("%d%d%d",&a,&b,&c);
E.push_back(Lu(b,1,c));
E.push_back(Lu(n+a,0,0-c));
V[b].push_back(E.size()-1);
V[n+a].push_back(E.size()-2);
}
E.push_back(Lu(n+n,inf,0));////汇点可以经过很多次,那么拆分成之后相连的边容量设成无限大
E.push_back(Lu(n,0,0));
V[n+n].push_back(E.size()-1);
V[n].push_back(E.size()-2);
MinCostMaxFlow(1,n+n);
printf("%d %d\n",fflow,ccost);
}
}