POJ 2387 Til the Cows Come Home

24 篇文章 0 订阅
11 篇文章 0 订阅

Question link

Solution 1

You can use Dijkstra algorithm to solut this question.

The following is the code that can be accepted

#include<iostream>
#include<queue>
#include<cstring>
#include<string>
#include<sstream>
#include<map>
#include<vector>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<stack>
#include<ctime>
using namespace std; 
#define rep(i,aa,bb) for(int i=aa;i<=bb;i++)
#define LL long long 
#define eps 0.000001
#define inf 0x3f3f3f3f
#define exp 0.000001
#define pai 3.141592654
#define random(x)   rand()%(x)
inline int read()
{
	int x=0,y=1;char a=getchar();while ( a>'9' || a<'0')	{if ( a=='-')y=-1;a=getchar();}
	while ( a>='0' && a<='9' ){	x=10*x+a-'0'; a=getchar();}return x*y;
}
#define N 1009
#define inf 999999999
bool vis[N];int dis[N],e[N][N];
int main()
{
//	freopen("1.txt","r",stdin);
	srand((int)time(0));
//	std::ios::sync_with_stdio(false);
	int t,n; 
	while ( scanf("%d%d",&t,&n) == 2 ){
		memset(e,0,sizeof(e));
		for ( int i = 1 ;i <= n; i++)
			for ( int j = 1; j <= n; j++)
			if ( i==j )	e[i][j] = 0; 
			else		e[i][j] = inf; 		
		rep(i,1,t){
			int a,b,c; 
			scanf("%d%d%d",&a,&b,&c);
			if ( e[a][b] > c )	
				e[a][b] = e[b][a] = c; 
		}
		rep(i,1,n)	dis[i] = e[1][i];
		memset(vis,0,sizeof(vis));
		int minx = inf;
		for (int ai = 1; ai <= n; ai++){
			 int u; minx = inf; 
			for (int bi = 1; bi <= n ; bi++){
				if ( minx > dis[bi] && vis[bi]==0 )	
					minx = dis[bi],u = bi; 
			}
			vis[u] = 1; 
			for (int ci = 1; ci <= n; ci++){
				if ( dis[ci] > dis[u] + e[u][ci])
					dis[ci] = dis[u] + e[u][ci];
			}
		}
		printf("%d\n",dis[n]);
	}	
	return 0;
}

Besides, you should pay attention to some details.

First at all , you need initialize the arrays called e,which storage the the cost of from u to v . Because the graph is bidirectional, the road from v to u is needed to make.
Secondly , initialization is very importance.
Third, the repeating edges will make the code wrong.

Solution 2

You can use Bellman-Ford algorithm to solut this question.

The following is the code that can be accepted

#include<iostream>
#include<queue>
#include<cstring>
#include<string>
#include<sstream>
#include<map>
#include<vector>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<stack>
#include<ctime>
using namespace std; 
#define rep(i,aa,bb) for(int i=aa;i<=bb;i++)
#define LL long long 
#define eps 0.000001
#define inf 0x3f3f3f3f
#define exp 0.000001
#define pai 3.141592654
#define random(x)   rand()%(x)
inline int read()
{
	int x=0,y=1;char a=getchar();while ( a>'9' || a<'0')	{if ( a=='-')y=-1;a=getchar();}
	while ( a>='0' && a<='9' ){	x=10*x+a-'0'; a=getchar();}return x*y;
}
#define N 1009
#define inf 999999999
bool vis[N];int dis[N];
struct road{
	int u,v,w; 
	road(){	
		u = 0;
		v = 0; 
		w = inf; 
	};
}r[N*4];
int main()
{
//	freopen("1.txt","r",stdin);
	srand((int)time(0));
	int t,n; 
	while ( scanf("%d%d",&t,&n) == 2 ){	
		rep(i,1,t){
			scanf("%d%d%d",&r[i].u,&r[i].v,&r[i].w);
			r[i+t].u = r[i].v; 	r[i+t].v = r[i].u; 	r[i+t].w = r[i].w; 
		}
		rep(i,1,n)	dis[i] = inf; 
		dis[1] = 0; 
		for (int ai = 1; ai <= n-1 ; ai++){
			for (int bi = 1; bi <= t*2; bi++){
				if ( dis[ r[bi].v ] > dis[ r[bi].u ] + r[bi].w ){
					 dis[ r[bi].v ] = dis[ r[bi].u ] + r[bi].w; 
				}
			}
		}		
		printf("%d",dis[n]);
	}	
	return 0;
}

Solution 3

You can use queue to optimize Bellman-Ford algorithm to solut this question.

#include<iostream>
#include<queue>
#include<cstring>
#include<string>
#include<sstream>
#include<map>
#include<vector>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<stack>
#include<ctime>
using namespace std; 
#define rep(i,aa,bb) for(int i=aa;i<=bb;i++)
#define LL long long 
#define eps 0.000001
#define inf 0x3f3f3f3f
#define exp 0.000001
#define pai 3.141592654
#define random(x)   rand()%(x)
inline int read()
{
	int x=0,y=1;char a=getchar();while ( a>'9' || a<'0')	{if ( a=='-')y=-1;a=getchar();}
	while ( a>='0' && a<='9' ){	x=10*x+a-'0'; a=getchar();}return x*y;
}
#define N 1009
bool vis[N];int dis[N];
struct road{
	int u,v,w,nx; 
	road(){	
		u = 0;
		v = 0; 
		w = inf; 
		nx = 0; 
	};
}r[N*4];
int hea[N]; int tot =0; 
inline void add_ead(int u,int v,int w){
	++tot;r[tot].u = u;r[tot].v = v; r[tot].w = w; r[tot].nx = hea[u] ; hea[u] = tot; 
}
queue<int>q; 
int main()
{
//	freopen("1.txt","r",stdin);
	srand((int)time(0));
	int t,n; 
	while ( scanf("%d%d",&t,&n) == 2 ){	
		tot = 0; 
		while ( !q.empty() ) q.pop(); 
		rep(i,1,t){
			int a,b,c; 
			a = read(); b = read() ; c = read();
			add_ead(a,b,c); add_ead(b,a,c);
		}
		q.push(1);
		vis[1] = true; 
		rep(i,1,n) dis[i] = inf; 
		dis[1] = 0; 
		while ( !q.empty() ){
			int u = q.front(); 
			q.pop();
			vis[ u ] = 0; 
			for(int i = hea[u]; i ; i = r[i].nx ){
				if ( dis[ r[i].v ] > dis[ r[i].u ] + r[i].w ){
					dis[ r[i].v ] = dis[ r[i].u ] + r[i].w ;
					if ( !vis[ r[i].v ] ){
						vis[ r[i].v ] = 1 ; 
						q.push(r[i].v);
					}
				}
			}
		}
		printf("%d",dis[n]);
	}	
	return 0;
}

Solution 4 (Dijstra + adjacency list)

#include<iostream>
#include<queue>
#include<cstring>
#include<string>
#include<sstream>
#include<map>
#include<vector>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<stack>
#include<ctime>
using namespace std; 
#define rep(i,aa,bb) for(int i=aa;i<=bb;i++)
#define mset(aaa,vvv)	memset(aaa,vvv,sizeof(aaa))
#define LL long long 
#define eps 0.000001
#define inf 0x3f3f3f3f
#define exp 0.000001

#define pai 3.141592654
#define random(x)   rand()%(x)
inline int read()
{
	int x=0,y=1;char a=getchar();while ( a>'9' || a<'0')	{if ( a=='-')y=-1;a=getchar();}
	while ( a>='0' && a<='9' ){	x=10*x+a-'0'; a=getchar();}return x*y;
}
#define N 1009
int dis[N];
struct road{
	int u,v,w,nx; 
	road(){	
		u = 0;	v = 0; 	w = inf; 	nx = 0; 
	};
}r[N*4];
int hea[N]; int tot =0; 
inline void add_ead(int u,int v,int w){
	++tot;r[tot].u = u;r[tot].v = v; r[tot].w = w; r[tot].nx = hea[u] ; hea[u] = tot; 
}
void init(){
	tot = 0; 
	mset(dis,0x3f);		
}
struct Heapnode{
	int u,d; 
	bool operator < (const Heapnode& rhs) const {
		return d < rhs.d; 
	}
};
void Dijkstra(){
	priority_queue<Heapnode>q; 
	dis[ 1 ] = 0; 
	Heapnode a; a.u = 1; a.d = 0; 
	q.push(a);
	while ( !q.empty() ){
		Heapnode x = q.top(); q.pop();
		int u = x.u; 
		if ( x.d != dis[u] )	continue; 
		for (int i = hea[u]; i ; i = r[i].nx ){
			if ( dis[ r[i].v ] > dis[ r[i].u ] + r[i].w ){
				dis[ r[i].v ] = dis[ r[i].u ] + r[i].w; 
				Heapnode b; b.u = r[i].v; b.d = dis[r[i].v]; 
				q.push(b);
			}
		}
	} 
}
int main()
{
//	freopen("1.txt","r",stdin);
	srand((int)time(0));
	int t,n; 
	while ( scanf("%d%d",&t,&n) == 2 ){	
		init();
		rep(i,1,t){
			int a,b,c; 
			a = read(); b = read() ; c = read();
			add_ead(a,b,c); add_ead(b,a,c);
		}
		Dijkstra();
		printf("%d",dis[n]);
	}	
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值