dijkstra
1 const int inf=0x3f3f3f3f; 2 const int maxv=1010; 3 const int maxe=1010; 4 5 struct Edge 6 { 7 int u,v,w; 8 int nex; 9 }e[maxe<<1]; 10 int head[maxv]; 11 int cnt=0; 12 void init() 13 { 14 memset(head,-1,sizeof(head)); 15 cnt=0; 16 } 17 void add(int u,int v,int w) 18 { 19 e[cnt].u=u; 20 e[cnt].v=v; 21 e[cnt].w=w; 22 e[cnt].nex=head[u]; 23 head[u]=cnt++; 24 } 25 26 typedef pair<int,int> PII; 27 int dis[maxv]; 28 int par[maxv]; 29 void dijkstra(int s) 30 { 31 priority_queue<PII,vector<PII>,greater<PII> > pq; 32 for(int i=0;i<maxv;i++) dis[i]=inf; 33 dis[s]=0; 34 pq.push(PII(0,s)); 35 while(!pq.empty()) 36 { 37 PII temp=pq.top(); 38 pq.pop(); 39 int u=temp.second; 40 if(dis[u]<temp.first) continue; 41 for(int i=head[u];i!=-1;i=e[i].nex) 42 { 43 if(dis[e[i].v]>dis[u]+e[i].w) 44 { 45 dis[e[i].v]=dis[u]+e[i].w; 46 par[e[i].v]=i; 47 pq.push(PII(dis[e[i].v],e[i].v)); 48 } 49 } 50 } 51 }
bellman_ford
1 const int inf=0x3f3f3f3f; 2 const int maxv=1010; 3 const int maxe=100010; 4 int n,m; 5 struct Edge 6 { 7 int u,v,w; 8 int nex; 9 }e[maxe<<1]; 10 int head[maxv]; 11 int cnt=0; 12 void init() 13 { 14 memset(head,-1,sizeof(head)); 15 cnt=0; 16 } 17 void add(int u,int v,int w) 18 { 19 e[cnt].v=v; 20 e[cnt].w=w; 21 e[cnt].nex=head[u]; 22 head[u]=cnt++; 23 } 24 int inq[maxv],deg[maxv],dis[maxv]; 25 26 bool bellman_ford() 27 { 28 queue<int> q; 29 memset(inq,0,sizeof(inq)); 30 memset(deg,0,sizeof(deg)); 31 for(int i=0;i<n;i++) 32 { 33 dis[i]=0; 34 inq[i]=1; 35 q.push(i); 36 deg[i]=1; 37 } 38 while(!q.empty()) 39 { 40 int u=q.front(); 41 q.pop(); 42 inq[u]=0; 43 for(int i=head[u];i!=-1;i=e[i].nex) 44 { 45 int v=e[i].v; 46 if(dis[v]>dis[u]+e[i].w) 47 { 48 dis[v]=dis[u]+e[i].w; 49 if(!inq[v]) 50 { 51 inq[v]=1; 52 q.push(v); 53 if(++deg[v]>=n) return 1; //有负环 这块有点问题,不知道等号成不成立 54 } 55 } 56 } 57 } 58 return 0; 59 }
Dinic
1 struct Edge{ 2 int u, v, flow, cap, nxt; 3 Edge(int u = 0, int v = 0, int cap = 0, int flow = 0, int nxt = 0) : u(u), v(v), cap(cap), flow(flow), nxt(nxt){} 4 }e[maxe << 1]; 5 int head[maxv]; 6 int cnt; 7 void init(){ 8 cnt = 0; 9 memset(head, -1, sizeof(head)); 10 } 11 void add(int u, int v, int cap){ 12 e[cnt] = Edge(u, v, cap, 0, head[u]); 13 head[u] = cnt++; 14 e[cnt] = Edge(v, u, 0, 0, head[v]); 15 head[v] = cnt++; 16 } 17 int a[maxv]; 18 char p[maxn][maxn]; 19 int s, t, N; 20 int vis[maxv], d[maxv], cur[maxv]; 21 int ans[maxn][maxn]; 22 23 int bfs(){ 24 memset(vis, 0, sizeof(vis)); 25 queue<int> q; 26 q.push(s); 27 vis[s] = 1; 28 d[s] = 0; 29 while(!q.empty()){ 30 int u = q.front(); 31 q.pop(); 32 for(int i = head[u]; ~i; i = e[i].nxt){ 33 int v = e[i].v; 34 if(!vis[v] && e[i].cap > e[i].flow){ 35 vis[v] = 1; 36 d[v] = d[u] + 1; 37 q.push(v); 38 } 39 } 40 } 41 return vis[t]; 42 } 43 int dfs(int u, int a){ 44 if(u == t || a == 0) return a; 45 int flow = 0, f; 46 for(int &i = cur[u]; ~i; i = e[i].nxt){ 47 int v = e[i].v; 48 if(d[v] == d[u] + 1 && (f = dfs(v, min(a, e[i].cap - e[i].flow))) > 0){ 49 e[i].flow += f; 50 e[i ^ 1].flow -= f; 51 flow += f; 52 a -= f; 53 if(a == 0) break; 54 } 55 } 56 return flow; 57 } 58 int Dinic(){ 59 int flow = 0; 60 while(bfs()){ 61 //for(int i = 0; i < N; i++) cur[i] = head[i]; 62 memcpy(cur, head, sizeof head); 63 flow += dfs(s, inf); 64 } 65 return flow; 66 }
ISPA
1 struct Edge{ 2 int u, v, cap, flow, nxt; 3 Edge(int u = 0, int v = 0, int cap = 0, int flow = 0, int nxt = 0) : u(u), v(v), cap(cap), flow(flow), nxt(nxt){} 4 }e[maxe<<1]; 5 int head[maxv]; 6 int cnt; 7 void init(){ 8 cnt = 0; 9 memset(head, -1, sizeof(head)); 10 } 11 void add(int u, int v, int cap){ 12 e[cnt] = Edge(u, v, cap, 0, head[u]); 13 head[u] = cnt++; 14 e[cnt] = Edge(v, u, 0, 0, head[v]); 15 head[v] = cnt++; 16 } 17 int d[maxv], vis[maxv], num[maxv], cur[maxv], pre[maxv]; 18 void bfs(){ 19 queue<int> q; 20 memset(vis, 0, sizeof vis); 21 memset(d, -1, sizeof d); 22 vis[t] = 1; 23 d[t] = 0; 24 q.push(t); 25 while(!q.empty()){ 26 int u = q.front(); 27 q.pop(); 28 for(int i = head[u]; ~i; i = e[i].nxt){ 29 int id = i & (-2); 30 int v = e[id].u; 31 if(!vis[v] && e[id].cap > e[id].flow) { 32 d[v] = d[u] + 1; 33 vis[v] = 1; 34 q.push(v); 35 } 36 } 37 } 38 } 39 int augment(){ 40 int u = t, a = inf; 41 while(u != s){ 42 int id = pre[u]; 43 a = min(a, e[id].cap - e[id].flow); 44 u = e[id].u; 45 } 46 u = t; 47 while(u != s){ 48 int id = pre[u]; 49 e[id].flow += a; 50 e[id ^ 1].flow -= a; 51 u = e[id].u; 52 } 53 return a; 54 } 55 int ISAP(){ 56 bfs(); 57 int flow = 0; 58 memset(num, 0, sizeof num); 59 for(int i = 0; i < N; i++){ 60 cur[i] = head[i]; 61 if(~d[i]) num[d[i]]++; 62 } 63 int u = s; 64 while(d[s] < N){ 65 if(u == t){ 66 flow += augment(); 67 u = s; 68 } 69 int ok = 0; 70 for(int i = cur[u]; ~i; i = e[i].nxt){ 71 int v = e[i].v; 72 if(e[i].cap > e[i].flow && d[u] == d[v] + 1){ 73 ok = 1; 74 pre[v] = i; 75 cur[u] = i; 76 u = v; 77 break; 78 } 79 } 80 if(!ok){ 81 int m = N - 1; 82 for(int i = head[u]; ~i; i = e[i].nxt){ 83 int v = e[i].v; 84 if(e[i].cap > e[i].flow && ~d[v]) m = min(m, d[v]); 85 } 86 if(--num[d[u]] == 0) break; 87 num[d[u] = m + 1]++; 88 cur[u] = head[u]; 89 if(u != s) u = e[pre[u]].u; 90 } 91 } 92 return flow; 93 }
求边双连通分量
(每个边双连通分量内部无桥)
1 const int maxv=1010; 2 struct Edge{ 3 int v,nex; 4 bool iscut; 5 }e[maxv<<2]; 6 int head[maxv]; 7 int cnt=0; 8 void init(){ 9 memset(head,-1,sizeof(head)); 10 cnt=0; 11 } 12 void add(int u,int v){ 13 e[cnt].iscut=0; 14 e[cnt].v=v; 15 e[cnt].nex=head[u]; 16 head[u]=cnt++; 17 } 18 19 int pre[maxv];// 时间戳 20 int bccno[maxv];// 标记该点属于的bcc 21 int dfsk,bcc_cnt; 22 bool vis[maxv]; 23 24 int dfs(int u,int id){ 25 int lowu=pre[u]=++dfsk; 26 for(int i=head[u];i!=-1;i=e[i].nex){ 27 int v=e[i].v; 28 if(i==(id^1)) continue;//// 反向边 29 if(!pre[v]){ 30 int lowv=dfs(v,i); 31 lowu=min(lowv,lowu); 32 if(lowv>pre[u]) e[i].iscut=e[i^1].iscut=true; 33 } 34 else lowu=min(lowu,pre[v]); 35 } 36 return lowu; 37 } 38 void dfs1(int u){ 39 vis[u]=1; 40 bccno[u]=bcc_cnt; 41 for(int i=head[u];i!=-1;i=e[i].nex){ 42 if(e[i].iscut) continue; 43 if(!vis[e[i].v]) dfs1(e[i].v); 44 } 45 } 46 //n个点,bcc_cnt个边双连通分量(从1开始) 47 //可以有重边 48 void find_bcc(int n){ 49 memset(pre,0,sizeof(pre)); 50 memset(bccno,0,sizeof(bccno)); 51 memset(vis,0,sizeof(vis)); 52 dfsk=bcc_cnt=0; 53 for(int i=0;i<n;i++) if(!pre[i]) dfs(i,-1); 54 for(int i=0;i<n;i++) 55 if(!vis[i]) bcc_cnt++,dfs1(i); 56 }
1 const int maxv = 25010; 2 const int maxe = 50010; 3 struct Edge{ 4 int v, nxt; 5 bool iscut; 6 Edge(){} 7 Edge(int v, int nxt, bool iscut):v(v), nxt(nxt), iscut(iscut){} 8 }e[maxe<<1]; 9 int head[maxv], cnt; 10 void init(){ 11 memset(head, -1, sizeof head); 12 cnt = 0; 13 } 14 void add(int u, int v){ 15 e[cnt] = Edge(v, head[u], 0); 16 head[u] = cnt++; 17 e[cnt] = Edge(u, head[v], 0); 18 head[v] = cnt++; 19 } 20 int n, m; 21 int pre[maxv], bccno[maxv]; 22 bool vis[maxv]; 23 int dfsk, bcc_cnt; 24 25 int dfs1(int u, int id){ 26 int lowu = pre[u] = ++dfsk; 27 for(int i = head[u]; ~i; i = e[i].nxt){ 28 if(i == (id ^ 1)) continue; 29 int v = e[i].v; 30 if(!pre[v]){ 31 int lowv = dfs1(v, i); 32 lowu = min(lowu, lowv); 33 if(lowv > pre[u]) e[i].iscut = e[i ^ 1].iscut = 1; 34 }else { 35 lowu = min(lowu, pre[v]); 36 } 37 } 38 return lowu; 39 } 40 int dfs2(int u){ 41 vis[u] = 1; 42 bccno[u] = bcc_cnt; 43 for(int i = head[u]; ~i; i = e[i].nxt){ 44 if(e[i].iscut) continue; 45 if(!vis[e[i].v]) dfs2(e[i].v); 46 } 47 } 48 49 void find_bcc(int n){ 50 memset(pre, 0, sizeof pre); 51 memset(vis, 0, sizeof vis); 52 memset(bccno, 0, sizeof bccno); 53 dfsk = bcc_cnt = 0; 54 for(int i = 1; i <= n; i++) if(!pre[i]) dfs1(i, -1); 55 for(int i = 1; i <= n; i++) if(!vis[i]){ 56 bcc_cnt++; 57 dfs2(i); 58 } 59 }
求点双连通分量(注意求的是极大子图)
(每个点双连通分量内部无割顶)
1 const int maxv=1010; 2 const int maxe=1000010; 3 int n,m; 4 struct Edge{ 5 int u,v,nex; 6 }e[maxe<<1]; 7 int head[maxv]; 8 int cnt=0; 9 void add(int u,int v){ 10 e[cnt].u=u; 11 e[cnt].v=v; 12 e[cnt].nex=head[u]; 13 head[u]=cnt++; 14 } 15 void init(){ 16 memset(head,-1,sizeof(head)); 17 cnt=0; 18 } 19 20 int pre[maxv]; //时间戳 21 int iscut[maxv]; //标记是否是割顶 22 int bccno[maxv]; //标记该点属于哪个连通分量 23 int dfsk,bcc_cnt; 24 vector<int> bcc[maxv]; //存连通分量里的点 25 stack<int> s; //存边的标号 26 27 int dfs(int u,int f){ 28 int lowu=pre[u]=++dfsk; 29 int child=0; 30 for(int i=head[u];i!=-1;i=e[i].nex){ 31 int v=e[i].v; 32 if(!pre[v]){ 33 s.push(i); 34 child++; 35 int lowv=dfs(v,u); 36 lowu=min(lowu,lowv); 37 if(lowv>=pre[u]){ 38 iscut[u]=1; 39 bcc_cnt++; 40 bcc[bcc_cnt].clear(); //bcc从1开始编号 41 for(;;){ 42 int te=s.top(); 43 s.pop(); 44 Edge p=e[te]; 45 if(bccno[p.u]!=bcc_cnt) {bcc[bcc_cnt].push_back(p.u);bccno[p.u]=bcc_cnt; } 46 if(bccno[p.v]!=bcc_cnt) {bcc[bcc_cnt].push_back(p.v);bccno[p.v]=bcc_cnt; } 47 if(p.u==u&&p.v==v) break; 48 } 49 } 50 }else if(pre[v]<pre[u]&&v!=f){ 51 s.push(i); 52 lowu=min(lowu,pre[v]); 53 } 54 } 55 if(f<0&&child==1) iscut[u]=0; 56 return lowu; 57 } 58 59 void find_bcc(int n) 60 { 61 memset(pre,0,sizeof(pre)); 62 memset(iscut,0,sizeof(iscut)); 63 memset(bccno,0,sizeof(bccno)); 64 dfsk=bcc_cnt=0; 65 for(int i=0;i<n;i++) if(!pre[i]) 66 dfs(i,-1); 67 }
强连通分量
1 const int maxv=10010; 2 const int maxe=100010; 3 int n,m; 4 struct Edge{ 5 int v,nex; 6 }e[maxe<<1]; 7 int head[maxv]; 8 int cnt=0; 9 void init(){ 10 memset(head,-1,sizeof(head)); 11 cnt=0; 12 } 13 void add(int u,int v){ 14 e[cnt].v=v; 15 e[cnt].nex=head[u]; 16 head[u]=cnt++; 17 } 18 int pre[maxv]; //时间戳 19 int low[maxv]; 20 int sccno[maxv]; //标记属于哪个强连通分量 21 int dfsk,scc_cnt; //scc_cnt是强连通分量个数,从1到scc_cnt 22 stack<int> s; 23 24 void dfs(int u){ 25 pre[u]=low[u]=++dfsk; 26 s.push(u); 27 for(int i=head[u];i!=-1;i=e[i].nex){ 28 int v=e[i].v; 29 if(!pre[v]){ 30 dfs(v); 31 low[u]=min(low[u],low[v]); 32 } 33 else if(!sccno[v]) //还在栈里! 34 low[u]=min(low[u],low[v]); 35 } 36 if(pre[u]==low[u]){ 37 scc_cnt++; 38 for(;;){ 39 int x=s.top(); 40 s.pop(); 41 sccno[x]=scc_cnt; 42 if(x==u) break; 43 } 44 } 45 } 46 void find_scc(int n){ 47 memset(pre,0,sizeof(pre)); 48 memset(low,0,sizeof(low)); 49 memset(sccno,0,sizeof(sccno)); 50 dfsk=scc_cnt=0; 51 for(int i=0;i<n;i++) if(!pre[i]) dfs(i); 52 }
TwoSat
1 struct TwoSAT 2 { 3 int n; 4 vector<int> G[maxn<<1]; 5 bool mark[maxn<<1]; 6 int s[maxn<<1],c; 7 8 bool dfs(int x) 9 { 10 if(mark[x^1]) return false; 11 if(mark[x]) return true; 12 mark[x]=true; 13 s[c++]=x; 14 for(int i=0;i<G[x].size();i++) 15 if(!dfs(G[x][i])) return false; 16 return true; 17 } 18 19 void init(int n) 20 { 21 this->n=n; 22 for(int i=0;i<n*2;i++) G[i].clear(); 23 memset(mark,0,sizeof(mark)); 24 } 25 26 void add_clause(int x,int xv,int y,int yv) 27 { 28 x=x*2+xv; 29 y=y*2+yv; 30 G[x^1].push_back(y); 31 G[y^1].push_back(x); 32 } 33 34 bool solve() 35 { 36 for(int i=0;i<n*2;i+=2) 37 if(!mark[i]&&!mark[i^1]) 38 { 39 c=0; 40 if(!dfs(i)) 41 { 42 while(c>0) mark[s[--c]]=false; 43 if(!dfs(i+1)) return false; 44 } 45 } 46 return true; 47 } 48 }solver;
朱刘算法
1 struct Edge{ 2 int u, v, w; 3 Edge(int u = 0, int v = 0, int w = 0) : u(u), v(v), w(w) {} 4 }e[maxe]; 5 6 int pre[maxn], id[maxn], vis[maxn]; 7 LL in[maxn]; 8 /* 9 * n个点(标号1到n)(有时要添加虚拟节点0) 10 * m条边(0到m-1) 11 */ 12 LL Dir_MST(int n, int m){ 13 int rt = 0; 14 LL ans = 0; 15 for(int i = 1; i <= n; i++) e[m++] = Edge(rt, i, 0); //添加虚拟节点rt = 0 16 n++; 17 int cnt = m; 18 while(true) { 19 //找最小入边 20 for(int i = 0; i < n; i++) in[i] = inf; 21 for(int i = 0; i < cnt; i++) { 22 int u = e[i].u, v = e[i].v, w = e[i].w; 23 if(w < in[v] && u != v) { 24 in[v] = w; 25 pre[v] = u; 26 } 27 } 28 for(int i = 0; i < n; i++){ 29 if(i == rt) continue; 30 if(in[i] == inf) return -1; // 有点没有入边,无法到达 31 } 32 //找环 33 int cntnode = 0; 34 memset(vis, -1, sizeof(vis)); 35 memset(id, -1, sizeof(id)); 36 in[rt] = 0; 37 for(int i = 0; i < n; i++){ //标记每个环 38 ans = ans + in[i]; 39 int v = i; 40 while(vis[v] != i && v != rt && id[v] == -1) { //每个点寻找其前序点,要么最终寻找至根部,要么找到一个环 41 vis[v] = i; 42 v = pre[v]; 43 } 44 if(id[v] == -1 && v != rt){ //缩点 45 for(int u = pre[v]; u != v; u = pre[u]) id[u] = cntnode; 46 id[v] = cntnode++; 47 } 48 } 49 if(cntnode == 0) break; //无环 则break 50 51 //建立新图 52 for(int i = 0; i < n; i++){ 53 if(id[i] == -1) id[i] = cntnode++; 54 } 55 for(int i = 0; i < cnt; i++){ 56 int v = e[i].v; 57 e[i].u = id[e[i].u]; 58 e[i].v = id[e[i].v]; 59 if(e[i].u != e[i].v) e[i].w -= in[v]; 60 } 61 n = cntnode; 62 rt = id[rt]; 63 } 64 return ans; 65 }