POJ1511 Invitation Cards [最短路,dijstra+heap,spfa]
来源:互联网 发布:excel剔除某些数据 编辑:程序博客网 时间:2024/05/07 14:09
题意:
给定节点数n,和边数m,边是单向边.
问从1节点出发到2,3,...n 这些节点路程和从从这些节点回来到节点1的路程和最小值。
思路:
很显然的最短路,先以1为起点进行一次最短路,然后再将边反向一下再以1为起点进行一下最短路。
这题的意义在于数据,一般的dijstra的O(N^2)显然没法过。
先用dijstra+heap试试。(以前被这个heap唬到了,其实heap直接用priority_queue实现即可)
//36412K1829MS#include<iostream>#include<vector>#include<string>#include<queue>#include<algorithm>#define llong long long#define Abs(a) ((a)>0?(a):-(a))#define Mod(a,b) (((a)-1+(b))%(b)+1)using namespace std;const int N=1000005;const int inf=1e10;int n,m;int a[N][3];struct{int w,v,next;}edge[N];int edgehead[N];llong d[N];bool vis[N];int k;void addedge(int u,int v,int w){edge[k].v=v;edge[k].w=w;edge[k].next=edgehead[u];edgehead[u]=k++;}struct cmp//注意priority_queue的cmp写的和sort里面的cmp的区别,前者是struct,后者是函数,而且比较大小的关系刚好是相反的。{bool operator()(const int a,const int b){return d[a]>d[b];}};llong dijstra(){memset(vis,0,sizeof(vis));priority_queue<int,vector<int>,cmp> que;for(int i=2;i<=n;i++)d[i]=inf;d[1]=0;que.push(1);while(!que.empty()){int u=que.top();vis[u]=true;que.pop();for(int i=edgehead[u];i;i=edge[i].next)//遍历节点u的每条出去的边{int v=edge[i].v;int w=edge[i].w;if(!vis[v]&&d[v]>d[u]+w)//如果是可松弛点即加入优先队列,d值越小越优先。{d[v]=d[u]+w;que.push(v);}}}llong ans=0;for(int i=1;i<=n;i++)ans+=d[i];return ans;}int main(){int cases;scanf("%d",&cases);while(cases--){k=1;memset(edgehead,0,sizeof(edgehead));memset(edge,0,sizeof(edge));scanf("%d%d",&n,&m);for(int i=1;i<=m;i++){scanf("%d%d%d",a[i],a[i]+1,a[i]+2);addedge(a[i][0],a[i][1],a[i][2]);}llong ans=dijstra();k=1;//将图的边反向之后再来一遍memset(edgehead,0,sizeof(edgehead));memset(edge,0,sizeof(edge));for(int i=1;i<=m;i++){addedge(a[i][1],a[i][0],a[i][2]);}ans+=dijstra();printf("%lld\n",ans);}return 0;}
其实效果不错。
下面是spfa的实现。
//36412K1969MS#include<iostream>#include<vector>#include<string>#include<queue>#include<algorithm>#define llong long long#define Abs(a) ((a)>0?(a):-(a))#define Mod(a,b) (((a)-1+(b))%(b)+1)using namespace std;const int N=1000005;const int inf=1e10;int n,m;int a[N][3];struct{int w,v,next;}edge[N];int edgehead[N];llong d[N];bool vis[N];int k;void addedge(int u,int v,int w){edge[k].v=v;edge[k].w=w;edge[k].next=edgehead[u];edgehead[u]=k++;}llong spfa(){memset(vis,0,sizeof(vis));for(int i=2;i<=n;i++)d[i]=inf;d[1]=0;queue<int> que;que.push(1);while(!que.empty()){int u=que.front();que.pop();vis[u]=false;//注意spfa的vis和dijstra的不同点,前者是判断是否在queue里而已,后者是判断是否已经是最优的点。for(int i=edgehead[u];i;i=edge[i].next){int v=edge[i].v;int w=edge[i].w;if(d[v]>d[u]+w)//这里不能写成if(!vis[v]&&d[v]>d[u]+w),原因看上一行的注释{d[v]=d[u]+w;if(!vis[v]){que.push(v);vis[v]=true;}}}}llong ans=0;for(int i=1;i<=n;i++)ans+=d[i];return ans;}int main(){int cases;scanf("%d",&cases);while(cases--){k=1;memset(edgehead,0,sizeof(edgehead));memset(edge,0,sizeof(edge));scanf("%d%d",&n,&m);for(int i=1;i<=m;i++){scanf("%d%d%d",a[i],a[i]+1,a[i]+2);addedge(a[i][0],a[i][1],a[i][2]);}llong ans=spfa();k=1;memset(edgehead,0,sizeof(edgehead));memset(edge,0,sizeof(edge));for(int i=1;i<=m;i++){addedge(a[i][1],a[i][0],a[i][2]);}ans+=spfa();printf("%lld\n",ans);}return 0;}第一道spfa题,都说spfa速度比较快又好写,但是从这题看来,dijstra+heap其实也没难写多少。
总结一下我对spfa的理解:
1.本质是维护一个队列。
只要这个队列里面还有元素,即这个最短路还可松弛,即此时此图还存在“更短路”。
2.还要注意bool vis[]数组,它只用来判断某节点是否存在队列中,因为如果已经在队列中了则无需入队,入队只会造成不必要的时间损失。
- POJ1511 Invitation Cards [最短路,dijstra+heap,spfa]
- POJ1511 Invitation Cards 【最短路】
- POJ1511 Invitation Cards(最短路)
- POJ1511-Invitation Cards-最短路
- POJ1511 Invitation Cards【SPFA】
- poj1511 Invitation Cards(最短路)
- SPFA最短路 POJ1511 Invitation Card
- POJ1511---Invitation Cards (最短路:邻接表+2次spfa)
- poj1511||hdu1535 Invitation Cards spfa
- POJ1511 Invitation Cards(SPFA)
- hdu 1535 || poj 1511 Invitation Cards(heap + dijstra || spfa)
- [最短路spfa]pku1511-Invitation Cards
- poj 1511 Invitation Cards(spfa最短路)
- POJ 1511 Invitation Cards 最短路SPFA
- HDOJ 1535 Invitation Cards 【最短路 SPFA】
- HDU1535 Invitation Cards(最短路,spfa)
- spfa-spfa(deque)-poj1511 - Invitation Cards
- poj1511 Invitation Cards Dijkstra+最小堆(heap)
- 第3题 reverse字符串
- MS11-080、MS11-046两个提权代码
- 单链表 算法(删除中间节点)
- ubuntu配置TortoiseHg的对比工具meld
- Android AIDL 远程服务器使用示例
- POJ1511 Invitation Cards [最短路,dijstra+heap,spfa]
- ServiceContract,OperationContract
- c#邮件带附件发送成功后附件文件不能及时删除
- 写代码如坐禅:你是哪一类程序员
- 什么是Windows服务,它的生命周期与标准的EXE程序有什么不同
- Ubuntu下Samba服务器的搭建
- OMNETPP+INED+OverSim组合进行P2P仿真
- SQL Server字符串处理函数大全
- 工程结构范例: