关于 atcoder 标准库 & ABC G
  • 板块学术版
  • 楼主optimize_2
  • 当前回复4
  • 已保存回复4
  • 发布时间2022/4/11 09:25
  • 上次更新2023/10/28 04:00:42
查看原帖
关于 atcoder 标准库 & ABC G
224978
optimize_2楼主2022/4/11 09:25

昨天晚上 ABC 的 G 脑抽了跑了 150150 遍费用流,然后直接 T 飞,赛后马上就想到每次增广只会多一流量,所以记录每次增广的费用即可。

今天看见最短解 500kb 左右,发现 #include <atcoder/all>,就想着用一用试试。

结果发现这个已经封装好了,只能 g.flow(),怎么做才能用这个标准库做到每次增广都记录答案呢?

附 最短解榜一老哥代码

#include<atcoder/all>
using namespace std;
int main(){
    int n;
    cin>>n;
    atcoder::mcf_graph<int,long>g(333);
    long o=1e12;
    for(int i=1;i<=150;i++)g.add_edge(0,i,1,0),g.add_edge(150+i,321,1,0);
    for(int i=0;i<n;i++){
        int a,b,c;
        cin>>a>>b>>c;
        g.add_edge(a,150+b,1,o-c);
    }
    int k=1;
    vector<long>v;
    for(;;k++){
        auto G=g;
        auto[f,c]=G.flow(0,321,k);
        if(f<k)break;
        v.push_back(o*k-c);
    }
    cout<<v.size()<<'\n';
    for(auto x:v)cout<<x<<'\n';
}

1289 ms,可以看到这位老哥打的也是暴力,然后因为标准库常熟小所以过了,我是大常数选手所以没过

然后榜二 45 ms,似乎只跑了一次费用流,然后用了奇怪的函数 g.slope,看不懂所以来求助谷友。

#include<atcoder/all>
using namespace std;
const long inf=1<<30;
main(){
  int n;
  cin>>n;
  atcoder::mcf_graph<int,long>G(302);
  for(int i=0;i<150;i++){
    G.add_edge(300,i,1,0);
    G.add_edge(150+i,301,1,0);
  }
  for(int i=0;i<n;i++){
    int a,b,c;
    cin>>a>>b>>c;
    a--,b--;
    G.add_edge(a,150+b,1,inf-c);
  }
  auto F=G.slope(300,301);
  cout<<F.back().first<<'\n';
  int x=0;
  long y=0;
  for(auto[p,q]:F){
    if(!p)continue;
    long d=(q-y)/(p-x);
    while(x<p){
      x++;
      y+=d;
      cout<<(inf*x-y)<<'\n';
    }
  }
}
2022/4/11 09:25
加载中...