我的马蜂
头文件
-
一般不用
<bits/stdc++.h>
-
想到什么写什么
-
不用
using namespace std
而用#define sd std::
但是会
using
自己的namespace
一些宏
#define UP(i, s, e) for(auto i=s; i!=e; ++i) // 用 auto 是因为 iterator 也能用
#define sd std::
#define ns namespace
#define ce constexpr
后两个也会用 vim 的 abbr
函数
-
大括号不换行,加不加空格看心情
-
一般的
main
函数:int main(){m::work(); return 0;}
有时也用
m::main
,m::mian
,m::solve
这些函数都为
void
防止自己忘了return 0;
多测时也会在
main
里多次调用m::work
有时也会在
main
里做一些初始化 e.g.freopen
,std::ios::sync_with_stdio(false)
等
- 剩余函数 & 变量全塞到
namespace m
里
塞入自己的
namespace
里可以定义叫min
的变量(bushi关于为什么叫
m
:原来是namespace my_namespace
,后来就开始偷懒
namespace
后会有一些给 vim 看的注释
example:
namespace m{ // }{{{ //... } // {}}}
- 函数间不空行
变量
- 读入的变量一律用 i+题中变量名命名
example:
第一行输入一个整数 \(n\) ->int in;
除非题中有 \(f\) 的变量(
if
不能用),此时会用jf
- 会开一个叫
ia
的意义不明的数组放题中给的数据
缩进
- tab
奇奇怪怪的位优化
- 不加,开-O2都一样
例
P2770
#include <cstdio>
#include <map>
#include <string>
#include <stack>
#include <bitset>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
#define sd std::
#define UP(i,s,e) for(auto i=s; i<e; ++i)
namespace flow{ // mcmf}{{{
using typ = int;
constexpr int V=100*2+2, E=100*99/2+100+100+2;
constexpr int EDGE_NIL = -1;
constexpr typ INF = (typ)0x3f3f3f3f3f3f3f3f;
struct Edge{ int to, nxt; typ cost, lf; } es[E*2+2*(1+EDGE_NIL)];
struct mypair{
typ dis; int id;
bool operator<(const mypair& a) const{ return dis > a.dis; }
mypair(typ d, int x){dis = d, id = x;}
};
typ dis[V], h[V];
int head[V], back[V];
sd bitset<V> vis;
int is, it, iv, cnt;
typ maxf, minc;
void init(int v, int s, int t){
is = s, it = t, iv = v;
cnt = (EDGE_NIL|1) + 1;
maxf = minc = 0;
sd fill(head, head+iv, EDGE_NIL);
}
void addflow(int s, int t, typ f, typ c){
es[cnt] = {t, head[s], c, f}, head[s] = cnt++;
es[cnt] = {s, head[t], -c, 0}, head[t] = cnt++;
}
bool dijk(){
sd priority_queue<mypair> todo;
sd fill(dis, dis+iv, INF);
vis.reset();
dis[is] = 0;
back[is] = EDGE_NIL;
todo.push({0, is});
while(!todo.empty()){
int s = todo.top().id;
todo.pop();
if(vis[s]) continue;
vis[s] = true;
for(int i=head[s]; i!=EDGE_NIL; i=es[i].nxt){
int t = es[i].to;
typ w = (typ)es[i].cost + h[s] - h[t];
if(es[i].lf && dis[t] > dis[s] + w){
dis[t] = dis[s] + w;
back[t] = i^1;
if(!vis[t]) todo.push({dis[t], t});
}
}
}
return dis[it] != INF;
}
void spfa(){
sd queue<int> todo;
vis.reset();
sd fill(h, h+iv, INF);
h[is] = 0;
todo.push(is);
while(!todo.empty()){
int s = todo.front();
todo.pop();
vis[s] = false;
for(int i=head[s]; i!=EDGE_NIL; i=es[i].nxt){
int t = es[i].to;
if(es[i].lf && h[t] > h[s] + es[i].cost){
h[t] = h[s] + es[i].cost;
if(!vis[t]) vis[t] = 1, todo.push(t);
}
}
}
}
void mcmf(){
spfa();
while(dijk()){
typ df = INF;
UP(i, 0, iv) h[i] += dis[i];
for(int i=back[it]; i!=EDGE_NIL; i=back[es[i].to]){
df = sd min(df, (typ)es[i^1].lf);
}
for(int i=back[it]; i!=EDGE_NIL; i=back[es[i].to]){
es[i].lf += df;
es[i^1].lf -= df;
}
maxf += df;
minc += df * h[it];
}
}
};// {}}}
namespace m { // }{{{
constexpr int N = 100;
int in, iv; char s[16];
sd string name[N];
sd map<sd string, int> ord;
void dfs(int, bool);
void work(){
scanf("%d%d", &in, &iv);
flow::init(2+in*2, 0, 1);
flow::addflow(0, 2, 2, 0);
flow::addflow(2+in*2-1, 1, 2, 0);
flow::addflow(2, 2+in, 1, 0);
flow::addflow(2+in-1, 2+in*2-1, 1, 0);
UP(i, 0, in){
scanf("%s", s);
name[i] = s;
ord.insert({name[i], i});
flow::addflow(2+i, 2+in+i, 1, -1);
}
UP(i, 0, iv){
int x, y;
scanf("%s", s);
x = ord[s];
scanf("%s", s);
y = ord[s];
if(x > y) sd swap(x, y);
flow::addflow(2+in+x, 2+y, 2, 0);
}
flow::mcmf();
if(flow::maxf != 2){
printf("No Solution!\n");
return;
}
printf("%d\n", -flow::minc);
dfs(2, true);
dfs(2, false);
if(flow::minc == -2) printf("%s\n", name[0].c_str());
}
using namespace flow;
void dfs(int x, bool fir){
if(x == 2+in-1){
if(fir) printf("%s\n", name[x-2].c_str());
return;
}
for(int i=head[x+in]; i!=EDGE_NIL; i=es[i].nxt){
if(es[i^1].lf){
if(fir) printf("%s\n", name[x-2].c_str());
dfs(es[i].to, fir);
if(!fir) printf("%s\n", name[x-2].c_str());
es[i^1].lf = 0;
break;
}
}
}
} // {}}}
int main() {
m::work();
return 0;
}