poj2387
2015-07-28 11:27
281 查看
题目名称:Til the Cows Come Home
题目链接:http://poj.org/problem?id=2387
题意:有N个点,T条边,问从1->N的最短路径
注意:INF不能设置太大,因为加法时可能溢出变负数,所以设为比最大值大一点就行,如10条最大1000的边则设置为10*1000+1(注意不是一条边的最大,是全部边和的最大)
思路:模板题,然后记得有重边
代码如下:只有dijkstra要判重边,spfa不用,,一般用spfa,负权可以用
dijkstra (O(n^2))
邻接矩阵vector版的spfa
邻接表的spfa
floyd 求每两点间的最短路 (O(n^3))
//这道题红果果的超时了。。
题目链接:http://poj.org/problem?id=2387
题意:有N个点,T条边,问从1->N的最短路径
注意:INF不能设置太大,因为加法时可能溢出变负数,所以设为比最大值大一点就行,如10条最大1000的边则设置为10*1000+1(注意不是一条边的最大,是全部边和的最大)
思路:模板题,然后记得有重边
代码如下:只有dijkstra要判重边,spfa不用,,一般用spfa,负权可以用
dijkstra (O(n^2))
#include<cstdio> #include<cstring> #include<iostream> #include<string> #include<algorithm> #include<map> #include<vector> #include<queue> using namespace std; const int maxn=1005; const int INF=0x3f3f3f3f; int dis[maxn][maxn]={INF}; int t,n; int dijkstra() { int d[maxn]; bool vis[maxn]={false}; memset(d,INF,sizeof(d)); d[1]=0; for(int i=1;i<=n;i++) { int x,m=INF; for(int j=1;j<=n;j++) { if(!vis[j]&&d[j]<=m) { m=d[j]; x=j; } } vis[x]=true; for(int j=1;j<=n;j++) { d[j]=min(d[j],d[x]+dis[x][j]); } } return d ; } int main() { while(scanf("%d%d",&t,&n)!=EOF) { memset(dis,INF,sizeof(dis)); int from,to,dist; for(int i=0;i<t;i++) { scanf("%d%d%d",&from,&to,&dist); if(dist<dis[from][to]) //判重边 { dis[from][to]=dist; dis[to][from]=dist; } } printf("%d\n",dijkstra()); } return 0; }
邻接矩阵vector版的spfa
#include<cstdio> #include<string> #include<queue> #include<iostream> #include<cstring> #include<vector> using namespace std; const int maxn=1005; const int INF=0x3f3f3f3f; int dis[maxn][maxn]={INF}; //记录权值 bool inque[maxn]; //记录是否在队列中 int d[maxn]; //记录最短路 int t,n; vector<int> vr[maxn]; void spfa(int s) { for(int i=1;i<=n;i++) { d[i]=INF; inque[i]=false; } queue<int> Q; d[s]=0; inque[s]=true; Q.push(s); while(!Q.empty()) { int x=Q.front(); Q.pop(); inque[x]=false; for(int i=0;i<vr[x].size();i++) { int y=vr[x][i]; if(d[y]>d[x]+dis[x][y]) { d[y]=d[x]+dis[x][y]; if(!inque[y]) { inque[y]=true; Q.push(y); } } } } } int main() { while(scanf("%d%d",&t,&n)!=EOF) { memset(dis,INF,sizeof(dis)); int from,to,dist; for(int i=0;i<t;i++) { scanf("%d%d%d",&from,&to,&dist); if(dist<dis[from][to]) { dis[from][to]=dist; dis[to][from]=dist; } vr[from].push_back(to); vr[to].push_back(from); } spfa(1); printf("%d\n",d ); } return 0; }
邻接表的spfa
#include<cstdio> #include<string> #include<queue> #include<iostream> #include<cstring> using namespace std; const int maxn=2005; const int INF=0x3f3f3f3f; //int dis[maxn][maxn]={INF}; //记录权值 bool inque[maxn]; //记录是否在队列中 int d[maxn]; //记录最短路 int t,n; int head[maxn]; struct Edge { int v,w,next; //v记录这一条边下个点,w记录该边的权值,next记录在这个点上的下一条边 }edge[maxn*2]; int cnt; void add_edge(int u,int v,int w) { edge[cnt].v=v; edge[cnt].w=w; edge[cnt].next=head[u]; head[u]=cnt++; } void init() { cnt=0; memset(head,-1,sizeof(head)); memset(inque,false,sizeof(inque)); // memset(dis,INF,sizeof(dis)); memset(d,INF,sizeof(d)); } void spfa(int s) { queue<int> Q; d[s]=0; Q.push(s); inque[s]=true; while(!Q.empty()) { int u=Q.front(); Q.pop(); inque[u]=false; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; int w=edge[i].w; if(d[v]>d[u]+w) { d[v]=d[u]+w; if(!inque[v]) { inque[v]=true; Q.push(v); } } } } } int main() { while(scanf("%d%d",&t,&n)!=EOF) { int from,to,dist; init(); for(int i=0;i<t;i++) { scanf("%d%d%d",&from,&to,&dist); add_edge(from,to,dist); add_edge(to,from,dist); } spfa(1); printf("%d\n",d ); } return 0; }
floyd 求每两点间的最短路 (O(n^3))
//这道题红果果的超时了。。
#include<cstdio> #include<string> #include<queue> #include<iostream> #include<cstring> using namespace std; const int maxn=1005; const int INF=0x3f3f3f3f; int d[maxn][maxn]; int n,t; void floyd() { for(int k=1;k<=n;k++) //注意先k,i和j的顺序可以变 for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) d[i][j]=min(d[i][j],d[i][k]+d[k][j]); } int main() { while(scanf("%d%d",&t,&n)!=EOF) { int from,to,dist; memset(d,INF,sizeof(d)); for(int i=1;i<=t;i++) { scanf("%d%d%d",&from,&to,&dist); if(dist<d[from][to]) { d[from][to]=dist; d[to][from]=dist; } } for(int i=1;i<=n;i++) { d[i][i]=0; } floyd(); printf("%d\n",d[1] ); } return 0; }
相关文章推荐
- Java IO学习【14】读取键盘录入
- C#设计模式(6)——原型模式(Prototype Pattern)
- iOS多线程的初步研究(四)-- NSTimer
- Js 冒泡事件阻止
- 键盘遮挡
- linux下搭建生成HLS所需的.ts和.m3u8文件
- progressbar 使用 Excel取数据
- hibernate如何连接数据库
- ubuntu14.04开机自动调节亮度
- ios 判断app是否为第一次启动
- JavaWeb学习——文件上传和下载
- HDU 1022 Train Problem I 【栈】
- Android平台利用Zxing生成二维码与解析图片中的二维码
- sql 事务
- 读Spring的源代码六:Controller mapping的注册过程
- LeetCode || Remove Duplicates from Sorted List II
- WebService或HTTP服务端接收请求转发消息到另一个服务端-实现思路
- Linux一键安装web环境全攻略(阿里云服务器)
- 非job用户修改数据库job执行情况
- uva 301 Transportation(回溯)