题意:传送门
题解:每天的道路都得完全不相同,然后通过将每个点进行拆点,拆为i和i',流量为1,费用为0,之后其他对应的边除了起点和终点不拆,然后其他的边都建为(u+n,v,1,w),之后跑最小费用最大流即可。
#include<bits/stdc++.h>
using namespace std;
const int MAX_V=1000;
const int INF=0x3f3f3f3f;
typedef pair<int,int>P;
struct edge{
int to,cap,cost,rev;
edge(int _to,int _cap,int _cost,int _rev):to(_to),cap(_cap),cost(_cost),rev(_rev){}
};
int n,m,u,v,w;
vector<edge>G[MAX_V];
int h[MAX_V];
int dist[MAX_V];
int prevv[MAX_V],preve[MAX_V];
void add_edge(int from,int to,int cap,int cost)
{
G[from].push_back(edge(to,cap,cost,G[to].size()));
G[to].push_back(edge(from,0,-cost,G[from].size()-1));
}
int res,f;
void min_cost_flow(int s,int t)
{
while(233){
priority_queue<P,vector<P>,greater<P> >que;
fill(dist,dist+3*n,INF);
dist[s]=0;
que.push(P(0,s));
while(!que.empty()){
P p=que.top();que.pop();
int v=p.second;
if(dist[v]<p.first){
continue;
}
for(int i=0;i<G[v].size();i++){
edge &e=G[v][i];
if(e.cap>0&&dist[e.to]>dist[v]+e.cost+h[v]-h[e.to]){
dist[e.to]=dist[v]+e.cost+h[v]-h[e.to];
prevv[e.to]=v;
preve[e.to]=i;
que.push(P(dist[e.to],e.to));
}
}
}
if(dist[t]==INF){
return ;
}
for(int v=0;v<3*n;v++){
h[v]+=dist[v];
}
int d=INF;
for(int v=t;v!=s;v=prevv[v]){
d=min(d,G[prevv[v]][preve[v]].cap);
}
f+=d;
res+=d*h[t];
for(int v=t;v!=s;v=prevv[v]){
edge &e=G[prevv[v]][preve[v]];
e.cap-=d;
G[v][e.rev].cap+=d;
}
}
return ;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=2;i<n;i++)add_edge(i,i+n,1,0);
for(int i=1;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);
if(u!=1){
add_edge(u+n,v,1,w);
}else{
add_edge(u,v,1,w);
}
}
min_cost_flow(1,n);
printf("%d %d\n",f,res);
return 0;
}