[bzoj1877]晨跑

很显然是网络流,对于点的限制,拆点建流量为1的边,之后跑最小费用最大流即可(由此很显然可以发现原图边的流量也只需要1)

复制代码
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 405
 4 struct ji{
 5     int nex,to,len,cost;
 6 }edge[N*N];
 7 queue<int>q;
 8 int E,n,m,x,y,z,ans1,ans2,head[N],d[N],from[N],vis[N];
 9 void add(int x,int y,int z,int w){
10     edge[E].nex=head[x];
11     edge[E].to=y;
12     edge[E].len=z;
13     edge[E].cost=w;
14     head[x]=E++;
15     if (E&1)add(y,x,0,-w);
16 }
17 bool spfa(){
18     memset(d,0x3f,sizeof(d));
19     memset(vis,0,sizeof(vis));
20     q.push(1);
21     d[1]=0;
22     while (!q.empty()){
23         int k=q.front();
24         q.pop();
25         vis[k]=0;
26         for(int i=head[k];i!=-1;i=edge[i].nex){
27             int v=edge[i].to;
28             if ((edge[i].len)&&(d[v]>d[k]+edge[i].cost)){
29                 d[v]=d[k]+edge[i].cost;
30                 from[v]=i;
31                 if (!vis[v]){
32                     vis[v]=1;
33                     q.push(v);
34                 }
35             }
36         }
37     }
38     return d[2*n]<0x3f3f3f3f;
39 }
40 int main(){
41     scanf("%d%d",&n,&m);
42     memset(head,-1,sizeof(head));
43     for(int i=1;i<=m;i++){
44         scanf("%d%d%d",&x,&y,&z);
45         add(x,y+n,1,z);
46     }
47     for(int i=1;i<=n;i++)add(i+n,i,1,0);
48     ans1=ans2=0;
49     while (spfa()){
50         ans1++;
51         ans2+=d[2*n];
52         for(int i=2*n;i>1;i=edge[from[i]^1].to){
53             edge[from[i]].len--;
54             edge[from[i]^1].len++;
55         }
56     }
57     printf("%d %d",ans1,ans2);
58 } 
View Code
复制代码

 

posted @   PYWBKTDA  阅读(88)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
点击右上角即可分享
微信分享提示