1379:热浪(heatwv)

1379:热浪(heatwv)

时间限制: 1000 ms         内存限制: 65536 KB
提交数: 2256     通过数: 1164 
【题目描述】
德克萨斯纯朴的民眾们这个夏天正在遭受巨大的热浪!!!他们的德克萨斯长角牛吃起来不错,可是他们并不是很擅长生產富含奶油的乳製品。Farmer John此时以先天下之忧而忧,后天下之乐而乐的精神,身先士卒地承担起向德克萨斯运送大量的营养冰凉的牛奶的重任,以减轻德克萨斯人忍受酷暑的痛苦。

FJ已经研究过可以把牛奶从威斯康星运送到德克萨斯州的路线。这些路线包括起始点和终点先一共经过T (1 ≤ T ≤ 2,500)个城镇,方便地标号為1到T。除了起点和终点外的每个城镇由两条双向道路连向至少两个其它的城镇。每条道路有一个通过费用(包括油费,过路费等等)。

给定一个地图,包含C (1 ≤ C ≤ 6,200)条直接连接2个城镇的道路。每条道路由道路的起点Rs,终点Re (1 ≤ Rs ≤ T; 1 ≤ Re ≤ T),和花费(1 ≤ Ci ≤ 1,000)组成。求从起始的城镇Ts (1 ≤ Ts ≤ T)到终点的城镇Te(1 ≤ Te ≤ T)最小的总费用。

【输入】
第一行: 4个由空格隔开的整数: T, C, Ts, Te;

第2到第C+1行: 第i+1行描述第i条道路。有3个由空格隔开的整数: Rs, Re和Ci。

【输出】
一个单独的整数表示从Ts到Te的最小总费用。数据保证至少存在一条道路。

【输入样例】
7 11 5 4
2 4 2
1 4 3
7 2 2
3 4 3
5 7 5
7 3 3
6 1 1
6 3 4
2 4 3
5 6 3
7 2 1
【输出样例】
7
【提示】
【样例说明】

5->6->1->4 (3 + 1 + 3)


模板题直接套模板

floyd算法只过7个点 ,3个点超时

# include<iostream>
# include<cstdio>
# define inf 0x3f3f3f3f
using namespace std;
const int maxn=2500+5;
int d[maxn][maxn];
int main()
{
	int n,m,s,w;
	cin>>n>>m>>s>>w;
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			if(i==j)
			d[i][j]=0;
			else d[i][j]=inf;
		}
	}
	for(int i=0;i<m;i++)
	{
		int u,v,ww;
		scanf("%d %d %d",&u,&v,&ww);
		u--;
		v--;
		d[u][v]=ww;
		d[v][u]=ww;
	}
	for(int k=0;k<n;k++)
	{
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<n;j++)
			   d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
		}
	}
	cout<<d[s-1][w-1]<<endl;
	return 0;
}

bellman算法直接ac

# include<iostream>
# include<cstdio>
# include<cstring>
# include<queue>
# define inf 0x3f3f3f3f
using namespace std;
const int maxn=2500+5;
struct edge{
	int from;
	int to;
	int dis;
	edge(int u,int v,int w):from(u),to(v),dis(w)
	{
	}
	edge()
	{
	}
};
struct Bellman{
	int n,m,u,v;
	vector<edge> edges;
	vector<int> g[maxn];
	int d[maxn];
	void init()
	{
		for(int i=0;i<n;i++)
		  g[i].clear();
		edges.clear();
	}
	void addedge(int u,int v,int w)
	{
		edges.push_back((edge){u,v,w});
		int m=edges.size();
		g[u].push_back(m-1);
	}
	void read_graph()
	{
		init();
		cin>>n>>m>>u>>v;
		
		for(int i=1;i<=m;i++)
		{
			int from,to,w;
			scanf("%d %d %d",&from,&to,&w);
			from--;
			to--;
			addedge(from,to,w);
			addedge(to,from,w);
			}
		
	}
	bool bellman(int s)
	{
		//memset(cnt,0,sizeof(cnt));
		//memset(inq,0,sizeof(inq));
		for(int i=0;i<n;i++)
		  d[i]=inf;
		d[s]=0;
		for(int i=1;i<n;i++)
		{
			
			for(int k=0;k<n;k++)
			{
			  for(int j=0;j<g[k].size();j++)
			    {
			    	edge e=edges[g[k][j]];
			    	if(d[e.to]>d[e.from]+e.dis)
			    	 d[e.to]=d[e.from]+e.dis;
				}
			
		     }
		}
		for(int k=0;k<n;k++)
			{
			  for(int j=0;j<g[k].size();j++)
			    {
			    	edge e=edges[g[k][j]];
			    	if(d[e.to]>d[e.from]+e.dis)
			    	  return false;
				}
			
		     }
		return true;

	}
};
int main()
{
	int u,v;
	Bellman ss;
	ss.read_graph();
	ss.bellman(ss.u-1);
	cout<<ss.d[ss.v-1]<<endl;
	return 0;
}

bellman的改良算法spfa直接ac

# include<iostream>
# include<cstdio>
# include<cstring>
# include<queue>
# define inf 0x3f3f3f3f
using namespace std;
const int maxn=2500+5;
struct edge{
	int from;
	int to;
	int dis;
	edge(int u,int v,int w):from(u),to(v),dis(w)
	{
	}
	edge()
	{
	}
};
struct Bellman{
	int n,m,u,v;
	vector<edge> edges;
	vector<int> g[maxn];
	bool inq[maxn];   //是否在队列中 
	int cnt[maxn];   //可以根据顶点进入队列次数是否>n,判断是否出现负环;  
	int d[maxn];
	void init()
	{
		for(int i=0;i<n;i++)
		  g[i].clear();
		edges.clear();
	}
	void addedge(int u,int v,int w)
	{
		edges.push_back((edge){u,v,w});
		int m=edges.size();
		g[u].push_back(m-1);
	}
	void read_graph()
	{
		init();
		cin>>n>>m>>u>>v;
		for(int i=1;i<=m;i++)
		{
			int from,to,w;
			scanf("%d %d %d",&from,&to,&w);
			from--;
			to--;
			addedge(from,to,w);
			addedge(to,from,w);
			}
		
	}
	bool bellman(int s)
	{
		queue<int> q;
		memset(cnt,0,sizeof(cnt));
		memset(inq,0,sizeof(inq));
		for(int i=0;i<n;i++)
		  d[i]=inf;
		d[s]=0;
		q.push(s);
		inq[s]=true;
		while(!q.empty())
		{
			int k=q.front();
			q.pop();
			inq[k]=false;//出队列 
			for(int j=0;j<g[k].size();j++)
			{
				edge e=edges[g[k][j]];
				if(d[e.to]>d[e.from]+e.dis)  //松弛算法 
				{   
				  d[e.to]=d[e.from]+e.dis;
				  if(!inq[e.to])   //不在队列中,加入队列
				  {
				     q.push(e.to);
					 inq[e.to]=true;
					 if(++cnt[e.to]>n)   //判断是否有负环 
					    return false;	
				  } 
				 } 
			}	
		}
		return true;
	}
};
int main()
{
	int u,v;
	Bellman ss;
	ss.read_graph();
	ss.bellman(ss.u-1);
	cout<<ss.d[ss.v-1]<<endl;
	return 0;
}

dijkstra算法基于优先级队列直接ac

# include<iostream>
# include<cstdio>
# include<cstring>
# include<queue>
# define inf 0x3f3f3f3f
using namespace std;
const int maxn=2500+5;
struct edge{
	int from;
	int to;
	int dis;
	edge(int u,int v,int w):from(u),to(v),dis(w)
	{
	}
	edge()
	{
	}
};
struct heapnode{
	int u;
	int d;
	heapnode(int uu,int dd):u(uu),d(dd)
	{
	}
	bool operator <(const heapnode &w) const
	{
		return w.d<d;
	}
};
struct Dijkstra{
	int n,m,u,v;
	vector<edge> edges;
	vector<int> g[maxn];
	bool inq[maxn];   //是否在队列中   
	int d[maxn];
	void init()
	{
		for(int i=0;i<n;i++)
		  g[i].clear();
		edges.clear();
	}
	void addedge(int u,int v,int w)
	{
		edges.push_back((edge){u,v,w});
		int m=edges.size();
		g[u].push_back(m-1);
	}
	void read_graph()
	{
		init();
		cin>>n>>m>>u>>v;
		for(int i=1;i<=m;i++)
		{
			int from,to,w;
			scanf("%d %d %d",&from,&to,&w);
			from--;
			to--;
			addedge(from,to,w);
			addedge(to,from,w);
			}
		
	}
   void  dijkstra(int s)
	{
		priority_queue<heapnode> q;
		//memset(cnt,0,sizeof(cnt));
		memset(inq,0,sizeof(inq));
		for(int i=0;i<n;i++)
		  d[i]=inf;
		d[s]=0;
		q.push((heapnode){s,0});
		while(!q.empty())
		{
			heapnode k=q.top();
			q.pop();
			if(inq[k.u])  continue;   //已经加入过队列
			inq[k.u]=true; 
			for(int j=0;j<g[k.u].size();j++)
			{
				edge e=edges[g[k.u][j]];
				if(d[e.to]>d[e.from]+e.dis)  //松弛算法 
				{   
				  d[e.to]=d[e.from]+e.dis;
				  q.push((heapnode){e.to,d[e.to]});
				 } 
			}	
		}
	}
};
int main()
{
	int u,v;
	Dijkstra ss;
	ss.read_graph();
	ss.dijkstra(ss.u-1);
	cout<<ss.d[ss.v-1]<<endl;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值