vis

割边模板

南楼画角 提交于 2019-12-04 09:24:45
判断方面,没有了割点的root的特判,并且==号去掉 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=1e3+10; 7 8 int dfn[maxn],low[maxn],head[maxn],vis[maxn]; 9 bool judge[maxn]; 10 int k,n,m,num,root; 11 struct Edge{ 12 int to,next; 13 }G[400010]; 14 struct node 15 { 16 int u,v; 17 }sto[maxn]; int cot; 18 //这个大小应该跟边数同步,但这里跟点的个数同步也能过; 19 //大概是因为割边的数量不多吧 20 void build(int u,int v){ 21 G[num].to=v;G[num].next=head[u];head[u]=num++; 22 } 23 24 void Tarjan(int u,int fa){ 25 int son=0; 26 vis[u]=1; //判断是否访问过,当访问完后定为2,不再访问; 27 k++; 28 dfn[u]=k; /

NOIP2009最优贸易(两遍SPFA/tarjan缩点+拓扑序dp)

非 Y 不嫁゛ 提交于 2019-12-04 09:18:51
传送门 本来想做一下tarjan缩点再拓扑序dp的题。 突然发现原来做过的这道可以用这种方法解决(原来是两遍SPFA)。 那么就合着一起总结一下吧! 原来一眼看到这道题,咦这不是水题嘛。 直接bfs一下找出能够达到1和n的点,然后这些点的max - min就好了呀! 然后愉快地敲好了代码,交上去全wa。 #include<bits/stdc++.h> #define LL long long #define N 100003 #define M 500003 #define INF 2100000000 using namespace std; int read() { int x=0,f=1;char s=getchar(); while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();} return x*f; } void print(int x) { if(x<0)x=-x,putchar('-'); if(x>10)print(x/10); putchar(x%10+'0'); } struct EDEG{ int nextt,to; }w[M*2],w2[M*2]; int head[N],head2[N],val[N]; int vis

网络流24题

南楼画角 提交于 2019-12-04 08:47:16
1.飞行员配对方案问题 题目链接 二分图匹配模板题 2.负载平衡问题 题目链接 题意: 公司有 n个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等。如何用最少搬运量可以使 n个仓库的库存数量相同。搬运货物时,只能在相邻的仓库之间搬运。输出最少搬运量。 思路: 求出平均数,显然最后所有仓库的货物数量都是平均数。如果点u的货物数比平均数大w,则源点到u有一条容量为w;费用为0的边,如果点u的货物数比平均数小w,则u到汇点有一条容量为w,费用为0的边。相邻两点之间有容量无穷大,费用为1的边,跑费用流即可。 #include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxm=1e3+5; const int maxn=105; const int INF=1e9; struct edge { int v,next,w,f; } E[maxm]; int tot=1,head[maxn];//tot必须设为1才能使反向边用^得到 void addedge(int u,int v,int w,int f) { E[++tot].v=v; E[tot].w=w; E[tot].f=f; E[tot].next=head[u]; head[u]=tot; } int n,m,s,t; int

题解 P4298 【[CTSC2008]祭祀】

主宰稳场 提交于 2019-12-04 08:11:57
题目链接 Solution [CTSC2008]祭祀 题目大意:求有向图最长反链,输出一种合法方案,以及一个点是否出现在至少一种合法方案里面 二分图 分析: 最长反链不好求,做个 \(Floyd\) 传递闭包,然后就是求最大点独立集了 然后 \(3min\) 淦了 \(CTSC\) 题? naive ,毒瘤SPJ让你输出方案 第二问我们先找一个最大匹配,从左侧点的选没有被匹配的跑 \(dfs\) ,每次从左到有走非匹配边,从右往左走匹配边。然后一路走一路标记,左边没有被标记过的点和右边被标记过的点就是最大点独立集 证明显然,匈牙利树不好想可以转成网络流 然后第三问,我们依次枚举删掉每一个点,如果删掉这个点之后答案减小了 \(1\) 那么这个点可能在最长反链中否则不可能 #include <cstdio> #include <cstring> #include <vector> using namespace std; const int maxn = 256,maxm = maxn * maxn; vector<int> G[maxn]; inline void addedge(int from,int to){G[from].push_back(to);} int n,m,ans,ban[maxn],match[maxn],vis[maxn],f[maxn][maxn],left

[模板大全] CSP前有用的板子(更新至两篇)

两盒软妹~` 提交于 2019-12-04 07:52:49
目录 图论 SPFA Dijkstra CSP前把重要的板子全部打一遍吧,顺便放一些下饭集锦(在每个板子的下面) 图论 SPFA ll dis[N]; bool vis[N]; queue<int> q; void spfa(int s) { memset(vis,0,sizeof(vis)); memset(dis,0x3f,sizeof(dis)); q.push(s);vis[s]=1;dis[s]=0; while(!q.empty()) { int u=q.front();q.pop();vis[u]=0; for(register int i=head[u];i;i=edge[i].next) { int v=edge[i].to; if(dis[v]>dis[u]+edge[i].dis) { dis[v]=dis[u]+edge[i].dis; if(!vis[v]) { q.push(v); vis[v]=1; } } } } } 注意事项:没什么好注意的,spfa极其优美,手感舒适 下饭集锦:v写成了edge[i].next Dijkstra struct Node { int u; ll dis; bool operator < (const Node &a) const { return a.dis<dis; } }; ll dis[N]; bool vis

USACO4.4 Frame Up【拓扑排序】

断了今生、忘了曾经 提交于 2019-12-04 07:51:09
题意居然还读了好久... 读完题目之后大概就知道拓扑排序了。用拓扑可以求出一些字母之间的关系,谁先,谁后。但是这个关系不是唯一确定的,所以就会产生多种方案(题目还要求按字典序输出所有的方案) 输出方案要麻烦一些,最刚开始还没有想到。可以用一个$dfs$,当这个点的入度变为$0$之后,就输出,递归到下一层,然后再回溯。 按字母的字典序枚举就可以输出按字典序排的方案。 1 /* 2 ID: Starry21 3 LANG: C++ 4 TASK: frameup 5 */ 6 #include<cstdio> 7 #include<algorithm> 8 #include<vector> 9 #include<cstring> 10 #include<queue> 11 #include<map> 12 #include<iostream> 13 using namespace std; 14 #define ll long long 15 #define INF 0x3f3f3f3f 16 #define N 35 17 int h,w,n/*一共n个图像(字母)*/; 18 char mp[N][N];//存图 19 int s[N],x[N],z[N],y[N];//每个字母边框的上下左右边在哪一行(列) 20 char kd[N];//存字母(1~n) 21 bool vis

dfs第二遍重学

笑着哭i 提交于 2019-12-04 07:15:34
---恢复内容开始---     1.先上个基础的全排列      #include<iostream> #include<cstring> using namespace std; const int maxn=1e3; int vis[maxn]; int p[maxn]; int n; int t=0; void dfs(int x) { if(x==n+1) { for(int i=1;i<=n;i++) cout<<p[i]<<" "; cout<<endl; return ; } for(int i=1;i<=n;i++) { if(!vis[i]) { vis[i]=1; p[x]=i; dfs(x+1); vis[i]=0; } } } int main() { while(cin>>n) { memset(vis,0,sizeof(vis)); dfs(1); } }     2.   HDU2614       这是个什么鬼题,依然不太明白题意,Hint部分还带有误导性。反正就是尽量让解题时间变长,找最长解题数目。对于Tij,如果符合条件,vis[j]通通不能再用。。。。但是代码是很简单,基本的dfs模板操作。        #include<iostream> #include<cstring> using namespace std; const int

未出现的最小正整数

徘徊边缘 提交于 2019-12-04 07:10:40
给出n个数,找出其中未出现的最小正整数。 只需要统计1-n是否出现,找最小未出现的即可,比如给出n个数,最多也是1-n都出现一次,那么最小未出现都是n+1,所以只需要统计1-n 代码: #include <stdio.h> #define MAX 100 int main() { int n,d; char vis[MAX + 1] = {0}; scanf("%d",&n); for(int i = 0;i < n;i ++) { scanf("%d",&d); if(d > 0 && d <= n) vis[d] = 1; } d = 1; while(d <= n && vis[d]) d ++; printf("%d",d); return 0; } 来源: https://www.cnblogs.com/8023spz/p/11845962.html

NOIP2009 最优贸易

江枫思渺然 提交于 2019-12-04 07:07:44
题意 在一张节点带有权值的图上找出一条从 \(1\) 到 \(n\) 的路径,使得路径上两点 \(p,q\) 满足先经过 \(p\) 再经过 \(q\) ,且 \(val[q]-val[p]\) 最大。 Luogu 分析 考虑跑两遍最短路,一遍求出经过每个节点时当前路径上的 \(val_{min}\) ,另一遍反向求出 \(val_{max}\) 。 于是就可以再建一个反图,两次SPFA,最后枚举每个节点找出 \(max(d[2][i]-d[1][i])\) 就完事辣。 但似乎有神仙只有32行代码...... 代码 #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 100003 #define M 500003 #define il inline #define re register #define INF 0x3f3f3f3f #define tie0 cin.tie(0),cout.tie(0) #define fastio ios::sync_with_stdio(false) #define File(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout)

CSP 前模板

对着背影说爱祢 提交于 2019-12-04 06:48:29
快CSP了,放一下自己打的板子。 /*tarjan 缩点*/ void tarajn(int x) { dfn[x]=low[x]=++cnt;zhan[++top]=x; vis[x]=1; for(int i=head[x];i;i=e[i].nt) { if(!dfn[e[i].to]) { tarjan(e[i].to); low[x]=min(low[x],low[e[i].to]); } else if(vis[e[i].to])low[x]=min(low[x],dfn[e[i].to]); } if(dfn[x]==low[x]) { int k;kuai++; do { k=zhan[top--]; c[k]=kuai; vis[k]=0; }while(x!=k); } } /*快速幂*/ LL ksm(LL a,LL b,LL mod) { LL res=1; for(;b;b>>=1,a=a*a%mod)if(b&1)res=res*a%mod; return res; } /*龟速乘*/ LL gsc(LL a,lLL b,LL mod) { LL res=0; for(;b;b>>=1,a=(a+a)%mod)if(b&1)res=(res+a)%mod; return res; } /*线性筛素数*/ for(int i=2;i<=M;++i) {