模板之图论
来源:互联网 发布:方舟生存进化淘宝 编辑:程序博客网 时间:2024/06/01 09:37
大神们都整理完了…我现在才来整理QAQ
最短路のSPFA:
可以判负环并且支持乱搞!
发一波最短路+判负环+记录路径(倒着输出)
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>using namespace std;const int MAX_V=2500+10;const int MAX_E=5200+10;int first[MAX_V],nxt[MAX_E<<1],d[MAX_V];struct edge{ int from,to,cost;}es[MAX_E<<1];int tot;int V,E,Ts,Te;void build(int ff,int tt,int dd){ es[++tot]=(edge){ff,tt,dd}; nxt[tot]=first[ff]; first[ff]=tot;}bool vis[MAX_V];int tim[MAX_V];int prev[MAX_V];queue<int>q;bool spfa(int s){ d[s]=0; vis[s]=1; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=0; for(int i=first[u];i!=-1;i=nxt[i]) { int v=es[i].to; if(d[v]>d[u]+es[i].cost) { d[v]=d[u]+es[i].cost; prev[v]=u; if(!vis[v]) { if(++tim[u]>V) return false; vis[v]=1; q.push(v); } } } } return true;}int main(){ memset(first,-1,sizeof(first)); memset(d,0x3f,sizeof(d)); memset(prev,-1,sizeof(prev)); scanf("%d%d%d%d",&V,&E,&Ts,&Te); for(int i=1;i<=E;i++) { int ff,tt,dd; scanf("%d%d%d",&ff,&tt,&dd); build(ff,tt,dd); build(tt,ff,dd); } if(spfa(Ts)) { cout<<d[Te]<<endl; for(int u=Te;u!=-1;u=prev[u]) cout<<u<<' '; puts(""); } else puts("-1"); return 0;}
次短路:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>using namespace std;const int SZ=200000+10;int first[SZ],nxt[SZ<<1],d[SZ],d2[SZ];struct edge{ int from,to,cost;}es[SZ<<1];int tot;void init(){ memset(first,-1,sizeof(first)); memset(d,0x3f,sizeof(d)); memset(d2,0x3f,sizeof(d2)); tot=0;}void build(int ff,int tt,int dd){ es[++tot]=(edge){ff,tt,dd}; nxt[tot]=first[ff]; first[ff]=tot;}bool vis[SZ];queue<int>q;void spfa(int s){ d[s]=0; vis[s]=1; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=0; for(int i=first[u];i!=-1;i=nxt[i]) { int v=es[i].to; if(d[v]>d[u]+es[i].cost) { d2[v]=d[v]; d[v]=d[u]+es[i].cost; if(!vis[v]) { vis[v]=1; q.push(v); } } else if(d[v]<d[u]+es[i].cost&&d2[v]>d[u]+es[i].cost) { d2[v]=d[u]+es[i].cost; if(!vis[v]) { vis[v]=1; q.push(v); } } else if(d2[v]>d2[u]+es[i].cost) { d2[v]=d2[u]+es[i].cost; if(!vis[v]) { vis[v]=1; q.push(v); } } } }}int main(){ init(); int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int ff,tt,dd; scanf("%d%d%d",&ff,&tt,&dd); build(ff,tt,dd); } spfa(1); if(d2[n]==0x3f3f3f3f) puts("-1"); else printf("%d\n",d2[n]); return 0;}
最短路のdijkstra:
发一波堆优化过的
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>using namespace std;const int MAX_V=2500+10;const int MAX_E=6200+10;int first[MAX_V],nxt[MAX_E<<1],d[MAX_V];struct edge{ int from,to,cost;}es[MAX_E<<1];struct heap{ int u,v;};int tot;int V,E,Ts,Te;void build(int ff,int tt,int dd){ es[++tot]=(edge){ff,tt,dd}; nxt[tot]=first[ff]; first[ff]=tot;}bool operator < (heap a,heap b){ return a.v > b.v;}bool vis[MAX_V];priority_queue<heap>q;void dij(int s){ d[s]=0; q.push((heap){s,0}); while(!q.empty()) { heap x=q.top(); q.pop(); int u=x.u; if(vis[u]) continue; vis[u]=1; for(int i=first[u];i!=-1;i=nxt[i]) { int v=es[i].to; if(d[v]>d[u]+es[i].cost) { d[v]=d[u]+es[i].cost; q.push((heap){v,d[v]}); } } }}int main(){ memset(first,-1,sizeof(first)); memset(d,0x3f,sizeof(d)); scanf("%d%d%d%d",&V,&E,&Ts,&Te); for(int i=1;i<=E;i++) { int ff,tt,dd; scanf("%d%d%d",&ff,&tt,&dd); build(ff,tt,dd); build(tt,ff,dd); } dij(Ts); cout<<d[Te]<<endl; return 0;}
最小生成树のkruskal:
裸题村村通~
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>using namespace std;const int MAX_E=10000+10;struct edge{ int from,to,cost;}es[MAX_E<<1];int fa[100+10];int cnt=0,ans=0,V;int find(int x){ if(fa[x]==x) return x; return fa[x]=find(fa[x]);}bool cmp(edge a,edge b){ return a.cost<b.cost;}void kruskal(){ for(int i=1;i<=V;i++) fa[i]=i; sort(es+1,es+cnt+1,cmp); for(int i=1;i<=cnt;i++) { int fx=find(es[i].from); int fy=find(es[i].to); if(fx!=fy) { fa[fx]=fy; ans+=es[i].cost; } }}int main(){ scanf("%d",&V); for(int i=1;i<=V;i++) for(int j=1;j<=V;j++) { int x; scanf("%d",&x); es[++cnt]=(edge){i,j,x}; } kruskal(); cout<<ans<<endl; return 0;}
Tarjar 找scc:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<stack>using namespace std;const int SZ=200000+10;int first[SZ],nxt[SZ<<1];struct edge{ int from,to,cost;}es[SZ<<1];int tot=0;void build(int ff,int tt){ es[++tot]=(edge){ff,tt}; nxt[tot]=first[ff]; first[ff]=tot;}int dfn[SZ],low[SZ],scc[SZ];int cnt=0,tim=0;int ans=0x3f3f3f3f;stack<int>s;void dfs(int u){ low[u]=dfn[u]=++tim; s.push(u); for(int i=first[u];i!=-1;i=nxt[i]) { int v=es[i].to; if(!dfn[v]) { dfs(v); low[u]=min(low[u],low[v]); } else if(!scc[v]) low[u]=min(low[u],dfn[v]); } if(low[u]==dfn[u]) { cnt++; int cnt2=0; while(true) { int x=s.top(); s.pop(); scc[x]=cnt; cnt2++; if(x==u) { if(cnt2>1) ans=min(ans,cnt2); break; } } }}int main(){ memset(first,-1,sizeof(first)); int n;scanf("%d",&n); for(int i=1;i<=n;i++) { int tt; scanf("%d",&tt); build(i,tt); } for(int i=1;i<=n;i++) { if(!dfn[i]) dfs(i); } cout<<ans; return 0;}
倍增lca+树上前缀和:
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;const int MAXN=50000+10;int first[MAXN],nxt[MAXN<<1],dis[MAXN];struct edge{ int from,to,cost;}es[MAXN<<1];int tot;int deep[MAXN],fa[MAXN],father[MAXN][30];void init(){ memset(first,-1,sizeof(first)); memset(dis,0x3f,sizeof(dis)); tot=0;}void build(int ff,int tt,int dd){ es[++tot]=(edge){ff,tt,dd}; nxt[tot]=first[ff]; first[ff]=tot;}void dfs(int u, int f){ deep[u]=deep[f]+1; fa[u]=f; father[u][0]=f; for(int i=1;i<=24;i++) father[u][i]=father[father[u][i-1]][i-1]; for(int i=first[u];i!=-1;i=nxt[i]) { int v=es[i].to; if(v==f) continue; dis[v]=dis[u]+es[i].cost; dfs(v,u); }}int lca(int x,int y){ if(deep[x]<deep[y]) swap(x,y); if(deep[x]>deep[y]) { int t=deep[x]-deep[y]; for(int i=24;i>=0;i--) if(t&(1<<i)) x=father[x][i]; } if(x!=y) { for(int i=24;i>=0;i--) { if(father[x][i]!=father[y][i]) { x=father[x][i]; y=father[y][i]; } } } else return x; return father[x][0];}int main(){ init(); int n; scanf("%d",&n); for(int i=1;i<n;i++) { int ff,tt,dd; scanf("%d%d%d",&ff,&tt,&dd); build(ff,tt,dd); build(tt,ff,dd); } int m; scanf("%d",&m);// deep[1]=1; dfs(0,0); int u,v; for(int i=1;i<=m;i++) { int ans=0; scanf("%d%d",&u,&v); int x=lca(u,v); //cout<<x<<endl; ans=dis[u]+dis[v]-dis[x]*2; printf("%d\n",ans); } return 0;}
拓扑排序:
#include<cstdio>#include<algorithm>#include<cstring>#include<iostream>#include<queue>using namespace std;const int SZ=100100;int rd[SZ];int ans,n,m;struct edge{ int from,to;}es[SZ];int tot,first[SZ],nxt[SZ];void build(int ff,int tt){ es[++tot]=(edge){ff,tt}; nxt[tot]=first[ff]; first[ff]=tot;}queue<int>q;void sort(){ for(int i=1;i<=n;i++) if(!rd[i]) { printf("%d ",i); q.push(i); } while(!q.empty()) { int u=q.front();q.pop(); for(int i=first[u];i!=-1;i=nxt[i]) { int v=es[i].to; rd[v]--; if(!rd[v]) { printf("%d ",v); q.push(v); } } }}int main(){ while(~scanf("%d",&n)) { memset(first,-1,sizeof(first)); int t; for(int i=1;i<=n;i++) { while(scanf("%d",&t)&&t) { rd[t]++; build(i,t); } } sort(); } return 0;}
0 0
- 模板之图论
- 图论之树链剖分模板
- 图论之2-sat模板
- 图论之离线lca模板
- 模板之函数模板
- 模板之---类模板
- 模板之函数模板
- C++模板之函数模板
- c++ 模板之函数模板
- c++模板之函数模板
- C++模板之函数模板
- c++学习之模板模板
- 数据结构之图——模板实现
- 图论模板
- 图论模板
- 图论模板
- 图论模板
- 图论模板
- centos7之lamp环境搭建
- pthread_cond_signal与pthread_cond_wait详解
- 初识vim
- shell基础
- PO BO VO DTO POJO DAO概念及其作用
- 模板之图论
- Codevs1269 匈牙利游戏 次短路spfa
- [bzoj2654] tree
- input标签file类型,选择多个文件进行上传
- windows下phpunit安装
- TopShelf-(01)控制台实例-Program
- 细说 ASP.NET Cache 及其高级用法
- 【Hacker Rank】06.Loops
- Android中TextView不获取焦点可以实现跑马灯的效果