图论之次小题型

原创 2016年06月01日 13:02:43

次短路:设最短路d[i],次短路d2[i],我们可以很明确次d2[i]=d[j]+(i,j)或d2[i]=d2[j]+(i,j)。dijsktra最短路的同时替换次短路即可。

参考程序:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#define maxn 10000
using namespace std;
struct Edge{
	int dist,to;
	Edge(int dist,int to):dist(dist),to(to){}
	bool operator < (Edge rhs) const {
		return dist>rhs.dist;
	}
};
int n,m;
struct Dijsktra{
	int dis[maxn],dis2[maxn];
	vector<Edge> G[maxn];
	int n,m;
	int first,second;
	void init(int n,int m){
		this->n=n;
		this->m=m;
		for (int i=0;i<n;i++)G[i].clear();
	}
	void addedge(int u,int v,int w){
		G[u].push_back(Edge(w,v));
		G[v].push_back(Edge(w,u));
	}
	void dijsktra(int s){
		memset(dis2,0x7f,sizeof(dis2));
		memset(dis,0x7f,sizeof(dis));
		dis[0]=0;
		priority_queue<Edge> Q;
		Q.push(Edge(0,0));
		while (!Q.empty()){
			Edge now=Q.top();Q.pop();
			int u=now.to,d=now.dist;
			if (dis2[u]<d)continue;
			for (int i=0;i<G[u].size();i++){
				Edge e=G[u][i];
				int d2=d+e.dist;
				if (dis[e.to]>d2){
					swap(dis[e.to],d2);
					Q.push(Edge(dis[e.to],e.to));
				}
				if (dis2[e.to]>d2 && dis[e.to]<d2){
					dis2[e.to]=d2;
					Q.push(Edge(dis2[e.to],e.to));
				}
			}
		}
		first=dis[n-1];second=dis2[n-1];
	}
}map;
int main(){
	scanf("%d%d",&n,&m);
	map.init(n,m);
	for (int i=0;i<m;i++){
		int u,v,w;
		scanf("%d%d%d",&u,&v,&w);u--;v--;
		map.addedge(u,v,w);
	}
	map.dijsktra(0);
	printf("%d\n%d",map.first,map.second);
	return 0;
}


次小生成树:除了涉及内容过深的算法,几乎没有特别优秀的算法,给出两个思路:

1.prim,然后删边增边。效率几经O(n^3)

2.从每个节点i遍历整个最小生成树,定义
F[j]为从i到j的路径上最大边的权值。遍历图求出F[j]的值,然后对于添加每条不在最小生成树中的边(i,j),新的生成树权值之和就是MinST + w(i,j) - F[j],记录其最小值,则为次小生成树.可以加入各种数据结构优化,比较麻烦,如果竞赛考到,一般不会太严格,此思路实现比较简单,效率O(n^2+m)。

这里给出去年打的pascal程序,C的日后再补上。

参考程序(prim):

var
  vis:array[0..11000]of boolean;
  dis,pre:array[0..11000]of longint;
  f,g,use:array[0..1100,0..1100]of longint;
  INF,n,m,max:longint;
function best(a,b:longint):longint;
begin
  if a>b then exit(a);
  exit(b);
end;
procedure openfile;
begin
  assign(input,'second_mst.in');reset(input);
  assign(output,'second_mst.out');rewrite(output);
end;
procedure closfile;
begin
  close(input);close(output);
end;
function prim:longint;
var
  i,tmp,pos,j:longint;
begin
  fillchar(dis,sizeof(dis),$7f shr 2);
  fillchar(pre,sizeof(pre),$ff);
  fillchar(vis,sizeof(vis),0);
  dis[1]:=0;INF:=dis[0]+1;max:=0;
  for i:=1 to n do
   begin
     tmp:=INF;
     for j:=1 to n do
      if (not vis[j])and(dis[j]<tmp) then
       begin
         tmp:=dis[j];
         pos:=j;
       end;
     if pre[pos]<>-1 then
      begin
        use[pre[pos],pos]:=2;
        use[pos,pre[pos]]:=2;
        for j:=1 to n do
         if vis[j] then
          f[j,pos]:=best(f[j,pre[pos]],g[pre[pos],pos]);
      end;
     vis[pos]:=true;
     max:=max+dis[pos];
     writeln(pos,' ',dis[pos]);
     for j:=1 to n do
      if (not vis[j])and(g[pos,j]>0)and(g[pos,j]<dis[j]) then
       begin
         dis[j]:=g[pos,j];
         pre[j]:=pos;
       end;
   end;
  exit(max);
end;
function second_mst:longint;
var
  sec,i,j:longint;
begin
  sec:=INF;
  for i:=1 to n do
   for j:=1 to n do
    if use[i,j]=1 then
     if max+g[i,j]-f[i,j]<sec then
      sec:=max+g[i,j]-f[i,j];
  exit(sec);
end;
procedure init;
var
  i,u,v,w:longint;
begin
  readln(n,m);
  for i:=1 to m do
   begin
     readln(u,v,w);
     g[u,v]:=w;g[v,u]:=w;
     use[u,v]:=1;use[v,u]:=1;
   end;
end;
procedure main;
begin
  //openfile;
  init;
  writeln(prim);
  write(second_mst);
  closfile;
end;
begin
  main;
end.


版权声明:本文为博主原创文章,但可以随意转载

(prim算法题型一)求最小生成树的权值和、路径、边值的最小和最大值。

1.输出最小生成树个边权值累加和 4 0 4 9 21 4 0 8 17 9 8 0 16 21 17 16 0 #include #include #define MaxInt 0x...

第二届河南省大学生程序设计竞赛题型简要分析

时间限制:   每题运行时间不超过1000MS 概览: 题数 类型 1 最短路径(广度优先搜索) 2 模拟 ...
  • wujun8
  • wujun8
  • 2012年05月02日 19:03
  • 2276

c语言面试题 指针30个常错题型

来源:http://blog.chinaunix.net/u1/58640/showart.php?id=1354073 记下来以备不时之需。 1. char * const p; char cons...

HDU 2546 饭卡 (01背包--经典题型!)

饭卡 Problem Description 电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额。如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后...

YTU-OJ-Problem L: 熟悉题型——自由设计(比较大小-类模板)

Problem L: 熟悉题型——自由设计(比较大小-类模板) Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 94  Solved: 79 ...
  • MIKASA3
  • MIKASA3
  • 2015年07月21日 09:16
  • 469

数据库原理期末考试题(经典题型)

数据库原理期末考试题(经典题型)

YTU-OJ-Problem K: 熟悉题型——代码完善(输出日期时间--友元函数)

Problem K: 熟悉题型——代码完善(输出日期时间--友元函数) Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 161  Solved:...
  • MIKASA3
  • MIKASA3
  • 2015年07月21日 09:14
  • 323

ZJU题型分类

ZJU题型分类又一: 初学者题: 1001 1037 1048 1049 1051 1067  1115 1151 1201 1205 1216 1240 1241 1242 1251 1292...

JS重点题型

JS重点题型(参考网络,书籍,自己总结整理) 1、闭包 下面这个JS程序的输出是什么 function Foo(){ var i=0; return function(){ console.lo...
  • kai_lun
  • kai_lun
  • 2017年04月09日 16:49
  • 182

如何动态删除题型

引言最近java版的itoo下的题库管理有一个新加题型的功能,但是没有实现动态删除。因为删除涉及到一些逻辑,所以在这里写下这篇博客,整理整理逻辑。删除的逻辑看一张图吧先: 也就是...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:图论之次小题型
举报原因:
原因补充:

(最多只允许输入30个字)