图论模板
来源:互联网 发布:江苏润和软件 编辑:程序博客网 时间:2024/06/05 18:00
来自AOJ GRL Graph Algorithm切题
部分来自上交红书
转载自http://blog.csdn.net/birdstorm_s/article/details/27855101
SPFA 单源最短路
- int r, v, e, x, y, d;
- int dist[MAXN];
- bool inque[MAXN];
- queue<int> que;
- vector<pair<int,int> > g[MAXN];
- void spfa()
- {
- memset(dist,0x3f,sizeof dist);
- dist[r]=0;
- while(!que.empty()) que.pop();
- que.push(r);
- inque[r]=true;
- while(!que.empty()){
- int u=que.front();
- que.pop();
- int sz=g[u].size();
- For(i,0,sz){
- if(dist[u]+g[u][i].second<dist[g[u][i].first]){
- dist[g[u][i].first]=dist[u]+g[u][i].second;
- if(!inque[g[u][i].first]){
- inque[g[u][i].first]=true;
- que.push(g[u][i].first);
- }
- }
- }
- inque[u]=false;
- }
- }
- int main()
- {
- scanf("%d%d%d",&v,&e,&r);
- For(i,0,e){
- scanf("%d%d%d",&x,&y,&d);
- g[x].push_back(make_pair(y,d));
- }
- spfa();
- For(i,0,v){
- if(dist[i]==0x3f3f3f3f) puts("INF");
- else printf("%d\n",dist[i]);
- }
- return 0;
- }
SPFA 单源最短路(有负边权和负圈)
- int v, e, x, y, d;
- LL dist[MAXN][MAXN];
- int cnt[MAXN];
- bool inque[MAXN][MAXN];
- queue<int> que;
- vector<pair<int,int> > g[MAXN];
- bool spfa()
- {
- For(i,0,v) For(j,0,v) dist[i][j]=LONG_LONG_MAX;
- For(r,0,v){
- dist[r][r]=0;
- memset(cnt,0,sizeof cnt);
- while(!que.empty()) que.pop();
- que.push(r);
- inque[r][r]=true;
- while(!que.empty()){
- int u=que.front();
- que.pop();
- int sz=g[u].size();
- For(i,0,sz){
- int id=g[u][i].first;
- if(dist[r][u]+g[u][i].second<dist[r][id]){
- dist[r][id]=dist[r][u]+g[u][i].second;
- if(!inque[r][id]){
- cnt[id]++;
- if(cnt[id]>e) return false;
- inque[r][id]=true;
- que.push(id);
- }
- }
- }
- inque[r][u]=false;
- }
- }
- return true;
- }
- int main()
- {
- scanf("%d%d",&v,&e);
- For(i,0,e){
- scanf("%d%d%d",&x,&y,&d);
- g[x].push_back(make_pair(y,d));
- }
- if(spfa()){
- For(i,0,v) For(j,0,v){
- if(dist[i][j]==LONG_LONG_MAX) printf("INF%c",j==v-1?'\n':' ');
- else printf("%lld%c",dist[i][j],j==v-1?'\n':' ');
- }
- }
- else puts("NEGATIVE CYCLE");
- return 0;
- }
dfs 判环(1有环2无环)
dfs中第二个判断末尾若将r节点加入L队列即为topo排序
- int v, e, x, y;
- int inque[MAXN];
- bool flag=false;
- vector<int> g[MAXN];
- void dfs(int r)
- {
- if(inque[r]==1){
- flag=true;
- }
- if(!inque[r]){
- inque[r]=1;
- int sz=g[r].size();
- For(i,0,sz) dfs(g[r][i]);
- inque[r]=-1;
- }
- }
- int main()
- {
- scanf("%d%d",&v,&e);
- For(i,0,e){
- scanf("%d%d",&x,&y);
- g[x].push_back(y);
- }
- For(i,0,v){
- if(!inque[i]) dfs(i);
- if(flag) break;
- }
- printf("%d\n",flag);
- return 0;
- }
prim
- int x, y, v, e;
- LL d, ans;
- LL dist[MAXN];
- bool vis[MAXN];
- vector<pair<int,LL> > g[MAXN];
- LL prim()
- {
- memset(vis,0,sizeof vis);
- ans=0;
- For(i,0,v) dist[i]=LONG_LONG_MAX;
- dist[0]=0;
- For(i,0,v){
- int mark=-1;
- For(j,0,v){
- if(!vis[j]){
- if(mark==-1) mark=j;
- else if(dist[j]<dist[mark]) mark=j;
- }
- }
- if(mark==-1) break;
- vis[mark]=true;
- ans+=dist[mark];
- int sz=g[mark].size();
- For(j,0,sz){
- int u=g[mark][j].first;
- if(!vis[u]){
- dist[u]=min(dist[u],g[mark][j].second);
- }
- }
- }
- return ans;
- }
- int main()
- {
- scanf("%d%d",&v,&e);
- For(i,0,e){
- scanf("%d%d%lld",&x,&y,&d);
- g[x].push_back(make_pair(y,d));
- g[y].push_back(make_pair(x,d));
- }
- printf("%lld\n",prim());
- return 0;
- }
kruscal
- int x, y, v, e, tot;
- LL d, ans;
- int father[MAXN];
- struct edge{
- int from, to, w;
- edge(int from=0, int to=0, int w=0): from(from),to(to),w(w) {}
- }g[MAXN];
- int cmp(edge a, edge b)
- {
- return a.w<b.w;
- }
- void addedge(int x, int y, int w)
- {
- g[tot].from=x, g[tot].to=y, g[tot].w=w; tot++;
- g[tot].from=x, g[tot].to=y, g[tot].w=w; tot++;
- }
- int getfather(int x)
- {
- if(father[x]==x) return x;
- else return father[x]=getfather(father[x]);
- }
- LL kruscal()
- {
- sort(g,g+tot,cmp);
- int cnt=v;
- ans=0;
- For(i,0,v) father[i]=i;
- For(i,0,tot){
- int t1=getfather(g[i].from);
- int t2=getfather(g[i].to);
- if(t1!=t2){
- father[t1]=father[t2];
- ans+=g[i].w;
- if(cnt==1) break;
- }
- }
- return ans;
- }
- int main()
- {
- scanf("%d%d",&v,&e);
- tot=0;
- For(i,0,e){
- scanf("%d%d%lld",&x,&y,&d);
- addedge(x,y,d);
- }
- printf("%lld\n",kruscal());
- return 0;
- }
最小树形图
- int x, y, v, e, tot, r;
- double d, sum;
- double g[MAXN][MAXN];
- int more, que[MAXN], eg[MAXN];
- bool pass[MAXN], used[MAXN];
- inline void combine(int id, double &sum)
- {
- int tot=0, from;
- for(;id!=0&&!pass[id];id=eg[id]){
- que[tot++]=id;
- pass[id]=true;
- }
- for(from=0;from<tot&&que[from]!=id;++from);
- if(from==tot) return;
- more=1;
- For(i,from,tot){
- sum+=g[eg[que[i]]][que[i]];
- if(i!=from){
- used[que[i]]=true;
- For(j,1,v+1) if(!used[j]){
- g[id][j]=min(g[id][j],g[que[i]][j]);
- }
- }
- }
- For(i,1,v+1) if(!used[i]&&i!=id){
- For(j,from,tot){
- int k=que[j];
- g[i][id]=min(g[i][id],g[i][k]-g[eg[k]][k]);
- }
- }
- }
- double mdst(int root)
- {
- sum=0;
- memset(used,0,sizeof used);
- for(more=1;more;){
- more=0;
- memset(eg,0,sizeof eg);
- For(i,1,v+1){
- if(!used[i]&&i!=root){
- int k=0;
- For(j,1,v+1){
- if(!used[j]&&j!=i){
- if(k==0||g[j][i]<g[k][i])
- k=j;
- }
- }
- eg[i]=k;
- }
- }
- memset(pass,0,sizeof pass);
- For(i,1,v+1){
- if(!used[i]&&!pass[i]&&i!=root)
- combine(i,sum);
- }
- }
- For(i,1,v+1) if(!used[i]&&i!=root) sum+=g[eg[i]][i];
- return sum;
- }
- int main()
- {
- scanf("%d%d%d",&v,&e,&r);
- For(i,0,e){
- scanf("%d%d%lf",&x,&y,&d);
- g[x+1][y+1]=d;
- }
- printf("%.0lf\n",mdst(r+1));
- return 0;
- }
查找桥和关节点(割点)
- int v, e, x, y;
- int vis[MAXN], low[MAXN], dfn[MAXN];
- bool cut[MAXN], bridge[MAXN][MAXN];
- vector<int> g[MAXN];
- void cut_bridge(int cur, int father, int dep, int n)
- {
- vis[cur]=1; dfn[cur]=low[cur]=dep;
- int children=0;
- int sz=g[cur].size();
- For(i,0,sz){
- int u=g[cur][i];
- if(u!=father&&vis[u]==1){
- if(dfn[u]<low[cur])
- low[cur]=dfn[u];
- }
- if(!vis[u]){
- cut_bridge(u,cur,dep+1,n);
- children++;
- if(low[u]<low[cur]) low[cur]=low[u];
- if(father==-1&&children>1||father!=-1&&low[u]>=dfn[cur]) cut[cur]=true;
- if(low[u]>dfn[cur]) bridge[cur][u]=bridge[u][cur]=true;
- }
- }
- vis[cur]=2;
- }
- int main()
- {
- scanf("%d%d",&v,&e);
- For(i,0,e){
- scanf("%d%d",&x,&y);
- g[x].push_back(y);
- g[y].push_back(x);
- }
- cut_bridge(0,-1,0,v);
- For(i,0,v) if(cut[i]) printf("%d\n",i);
- return 0;
- }
前向星建图
- struct graph{
- typedef vector<int> vi;
- vi info, next, to;
- graph(int n=0, int m=0): to(0), next(0) {
- info.resize(n);
- next.reserve(m);
- to.reserve(m);
- }
- int edge_size(){ //返回边的数量
- return to.size();
- }
- int vertex_size(){ //返回值为最大点的编号-1
- return info.size();
- }
- void expand(int i){
- if(info.size()<i+1)
- info.resize(i+1);
- }
- void add(int i, int j){ //添加一条i到j的边
- expand(i), expand(j);
- to.push_back(j);
- next.push_back(info[i]);
- info[i]=to.size()-1;
- }
- void del_back(){ //删除最后一次添加的边
- int i;
- for(int i=0; i<info.size(); i++){
- if(info[i]==to.size()-1){
- info[i]=next.back();
- break;
- }
- }
- to.pop_back();
- next.pop_back();
- }
- void clear(){ //清空
- info.clear();
- next.resize(0);
- to.resize(0);
- }
- };
0 0
- 图论模板
- 图论模板
- 图论模板
- 图论模板
- 图论模板
- 图论模板整理
- ACM图论模板
- 图论总结模板
- 图论常用模板
- 图论常用模板
- 模板之图论
- 【模板】其他图论
- 图论模板
- 图论的模板
- 图论模板
- 图论模板
- 图论模板
- 图论算法模板整理
- PHP获取当前时间
- Ubuntu 下编译qt版webkit
- ecshop修改商品数量后自动更新购物车
- [ASP.NET MVC]通过对HtmlHelper扩展简化“列表控件”的绑定
- Java中Array的常用方法
- 图论模板
- 让网站飞起来01---浏览器缓存技术
- 编写读取内存的程序 ——keil uVision3 printf函数重定向到串口输出
- 让网站飞起来02--服务器缓存技术
- QT_PC实战常见问题_控件传值问题总结
- linux常用命令小结
- 利用偏回归平方和选择最优变量的逐步回归
- A. Queue on Bus Stop
- make file