library

This documentation is automatically generated by online-judge-tools/verification-helper

View the Project on GitHub beet-aizu/library

:heavy_check_mark: test/aoj/3168.test.cpp

Depends on

Code

// verification-helper: PROBLEM http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=3168

#include<bits/stdc++.h>
using namespace std;

#define call_from_test
#include "../../io/single.cpp"
#include "../../tools/chminmax.cpp"
#include "../../matching/bipartite.cpp"
#undef call_from_test

const int MAX = 303;
int G[MAX][MAX]={};

signed main(){
  cin.tie(0);
  ios::sync_with_stdio(0);

  int n,m,lim;
  cin>>n>>m>>lim;

  auto cs=read<char>(n);

  const int INF = 1e9;
  for(int i=0;i<n;i++)
    for(int j=0;j<n;j++)
      G[i][j]=INF;

  for(int i=0;i<n;i++) G[i][i]=0;

  for(int i=0;i<m;i++){
    int a,b;
    cin>>a>>b;
    a--;b--;
    G[a][b]=G[b][a]=1;
  }

  for(int k=0;k<n;k++)
    for(int i=0;i<n;i++)
      for(int j=0;j<n;j++)
        chmin(G[i][j],G[i][k]+G[k][j]);

  auto check=[&](int i,int j){
    int x=cs[i]-'a';
    int y=cs[j]-'a';
    return (((x+1)%26==y or (y+1)%26==x) and G[i][j]<=lim);
  };

  Bipartite bm(n);
  for(int i=0;i<n;i++)
    for(int j=0;j<i;j++)
      if(check(i,j)) bm.add_edge(i,j);

  cout<<bm.build()<<endl;
  return 0;
}
#line 1 "test/aoj/3168.test.cpp"
// verification-helper: PROBLEM http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=3168

#include<bits/stdc++.h>
using namespace std;

#define call_from_test
#line 1 "io/single.cpp"

#line 3 "io/single.cpp"
using namespace std;
#endif

//BEGIN CUT HERE
template<typename T=int>
vector<T> read(size_t n){
  vector<T> ts(n);
  for(size_t i=0;i<n;i++) cin>>ts[i];
  return ts;
}
//END CUT HERE
#ifndef call_from_test
signed main(){
  return 0;
}
#endif
#line 1 "tools/chminmax.cpp"

#line 3 "tools/chminmax.cpp"
using namespace std;
#endif
//BEGIN CUT HERE
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}
//END CUT HERE
#ifndef call_from_test
signed main(){
  return 0;
}
#endif
#line 1 "matching/bipartite.cpp"

#line 3 "matching/bipartite.cpp"
using namespace std;
#endif
//BEGIN CUT HERE
// O(N M)
struct Bipartite{
  int time;
  vector< vector<int> > G;
  vector<int> match,used,dead;

  Bipartite(int n):
    time(0),G(n),match(n,-1),used(n,-1),dead(n,0){}

  void add_edge(int u,int v){
    G[u].emplace_back(v);
    G[v].emplace_back(u);
  }

  int dfs(int v){
    used[v]=time;
    for(int u:G[v]){
      if(dead[u]) continue;
      int w=match[u];
      if((w<0) or (used[w]<time and dfs(w))){
        match[v]=u;
        match[u]=v;
        return 1;
      }
    }
    return 0;
  }

  int build(){
    int res=0;
    for(int v=0;v<(int)G.size();v++){
      if(dead[v] or ~match[v]) continue;
      time++;
      res+=dfs(v);
    }
    return res;
  }

  int disable(int v){
    assert(!dead[v]);
    int u=match[v];
    if(~u) match[u]=-1;
    match[v]=-1;
    dead[v]=1;
    time++;
    return ~u?dfs(u)-1:0;
  }

  int enable(int v){
    assert(dead[v]);
    dead[v]=0;
    time++;
    return dfs(v);
  }

  int cut_edge(int u,int v){
    assert(find(G[u].begin(),G[u].end(),v)!=G[u].end());
    assert(find(G[v].begin(),G[v].end(),u)!=G[v].end());
    G[u].erase(find(G[u].begin(),G[u].end(),v));
    G[v].erase(find(G[v].begin(),G[v].end(),u));
    if(match[u]==v){
      match[u]=match[v]=-1;
      return 1;
    }
    return 0;
  }
};
//END CUT HERE
#ifndef call_from_test
signed main(){
  return 0;
}
#endif
#line 10 "test/aoj/3168.test.cpp"
#undef call_from_test

const int MAX = 303;
int G[MAX][MAX]={};

signed main(){
  cin.tie(0);
  ios::sync_with_stdio(0);

  int n,m,lim;
  cin>>n>>m>>lim;

  auto cs=read<char>(n);

  const int INF = 1e9;
  for(int i=0;i<n;i++)
    for(int j=0;j<n;j++)
      G[i][j]=INF;

  for(int i=0;i<n;i++) G[i][i]=0;

  for(int i=0;i<m;i++){
    int a,b;
    cin>>a>>b;
    a--;b--;
    G[a][b]=G[b][a]=1;
  }

  for(int k=0;k<n;k++)
    for(int i=0;i<n;i++)
      for(int j=0;j<n;j++)
        chmin(G[i][j],G[i][k]+G[k][j]);

  auto check=[&](int i,int j){
    int x=cs[i]-'a';
    int y=cs[j]-'a';
    return (((x+1)%26==y or (y+1)%26==x) and G[i][j]<=lim);
  };

  Bipartite bm(n);
  for(int i=0;i<n;i++)
    for(int j=0;j<i;j++)
      if(check(i,j)) bm.add_edge(i,j);

  cout<<bm.build()<<endl;
  return 0;
}
Back to top page