POJ 1511: http://poj.org/problem?id=1511
n,m为 1000000
题目大意为: 从点1 到其余各个点,再返回,所有的最短路,一共为多少。
此题就是 队列优化后 的 Dijkstra 或者 Spfa。
使用了一下不熟练的 队列优化的Dijkstra ,一直WA。
找了很久的错误/(ㄒoㄒ)/~~
后来发现, 最短路的极大值 以前屡试不爽的 99999999 八个九不能用。题目数据真是让我害怕。我改成 九个九或者十个九救过了......
队列优化Dijkstra: 里面的注释是我以前自己写的......
#include"cstdio"
#include"iostream"
#include"cstring"
#include"algorithm"
#include"vector"
#include"cmath"
#include"queue"
#include"map"
using namespace std;
#define INF 9999999999
#define inf 1000009
#define loop(x,y,z) for(x=y;x<z;x++)
#define ll long long
int n,m,s,g; //s 为起点 g 为终点
int book[inf],dis[inf]; //book为标记,一个点作为中转点只能走一次
ll ans;
int bus[inf][3]; //dis 为起点到此点距离
struct Node //存储边
{
int to,w;
Node(int i,int j)
{
to=i;w=j;
}
bool operator< (const Node& i)const
{
return w>i.w;
}
};
vector<Node>edge[inf]; //edge 来存储每一个邻接边
priority_queue<Node>q; //优先队列用来取元素
void init()
{
int i;
memset(book,0,sizeof book);
loop(i,1,n+1)edge[i].clear();
while(!q.empty())q.pop();
loop(i,1,n+1)
dis[i]=INF;
dis[s]=0;
}
void Dijkstra()
{
int i,j,k;
q.push(Node(s,0)); //压入起点
while(!q.empty())
{
Node t=q.top();
q.pop();
int u=t.to;
//if(book[u])continue; //取出距离起点最小点(Dijkstra思想),取过就吐掉
book[u]=1;
int len=edge[u].size();
loop(i,0,len) //对中转点每一条邻接边 松弛
{
Node& e=edge[u][i];
if(dis[e.to]>dis[u]+e.w)
{
dis[e.to]=dis[u]+e.w;
q.push(Node(e.to,dis[e.to])); //压入此点时,压入的是节点号,以及节点到起点的距离 dis
}
}
}
}
void print()
{
int i;
loop(i,1,n+1)printf("%d ",dis[i]);
printf("\n");
}
int main()
{
int i,j,k,o,t;
int T;
scanf("%d",&T);
loop(o,1,T+1)
{
scanf("%d%d",&n,&m);
ans=0;
s=1;g=n; //起点和终点别忘记修改
init();
loop(t,1,m+1)
{
scanf("%d%d%d",&i,&j,&k);
bus[t][0]=i;
bus[t][1]=j;
bus[t][2]=k;
}
loop(t,1,m+1)
edge[bus[t][0]].push_back(Node(bus[t][1],bus[t][2]));
Dijkstra();
loop(i,1,n+1)ans+=(ll)dis[i];
init();
loop(t,1,m+1)
edge[bus[t][1]].push_back(Node(bus[t][0],bus[t][2]));
Dijkstra();
loop(i,1,n+1)ans+=(ll)dis[i];
printf("%lld\n",ans);
}
return 0;
}