您的位置:首页 > 其它

POJ_3013_Big Christmas Tree

2013-12-05 09:32 405 查看
这道题目TLE了好多次才过,有些点要注意的:

1.图是无向图来的

2.边数组要开10W以上

3.求最短路时,保存中间路径长度要用long long,当然结果也就是long long保存啦

4.当0==n或1==n,输出0,当0==m,输出No Answer;

5.INF要大一点,可以用0x7f7f7f7f7f7f7f7fLL;

参考代码(spfa):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Edge {
int to,next;
int dis;
}Edge;

const int MAXN = 200100;
const int MAXM = MAXN << 1;
const long long INF = 0x7f7f7f7f7f7f7f7fLL;

bool vis[MAXN];
Edge edge[MAXN];
Edge head[MAXN];
long long dis[MAXN];
int val[MAXN];
int queue[MAXM];
int total,n,m;

void init();
void add_edge(int from,int to,int dis);
void spfa(int src);

int main(int argc,char * argv[]) {
int i,j,k;
int x,y,z;
int Case,flag;
long long ans;
scanf("%d",&Case);
while (Case-->0) {
scanf("%d%d",&n,&m);
init();
for (i=1;i<=n;++i) scanf("%d",val+i);
for (i=1;i<=m;++i) {
scanf("%d%d%d",&x,&y,&z);
add_edge(x,y,z);
add_edge(y,x,z);
}
if (0 == n || 1 == n) {
printf("0\n");
continue;
}
if (0 == m) {
printf("No Answer\n");
continue;
}
spfa(1);
flag = 1;
ans = 0LL;
for (i=2;i<=n;++i) {
if (INF == dis[i]) {
flag = 0;
break;
}
ans += dis[i] * val[i];
}
if (!flag) {
printf("No Answer\n");
} else {
printf("%lld\n",ans);
}
}
return 0;
}

void spfa(int src) {
int p,num;
int front,tail,cur;
memset(dis,0x7f,sizeof(dis));
memset(vis,0,sizeof(vis));
dis[src] = 0;
vis[src] = 1;
tail = 0;
front = -1;
queue[0] = src;
while (front != tail) {
++front;
if (front >= MAXM) front = 0;
cur = queue[front];
p = head[cur].next;
while (p) {
if (-1 == dis[edge[p].to] || dis[edge[p].to] - edge[p].dis > dis[cur]) {
dis[edge[p].to] = dis[cur] + edge[p].dis;
if (!vis[edge[p].to]) {
vis[edge[p].to] = 1;
++tail;
if (tail >= MAXM) tail = 0;
queue[tail] = edge[p].to;
}
}
vis[cur] = 0;
p = edge[p].next;
}
}

}

void init() {
total = 0;
for (int i=0;i<=n;++i)
head[i].next = 0;
}

void add_edge(int from,int to,int dis) {
++total;
edge[total].to = to;
edge[total].dis = dis;
edge[total].next = head[from].next;
head[from].next = total;
}

参考代码(dijkstra+priority_queue):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <queue>
using namespace std;

typedef struct Edge {
int to,next;
int dis;
}Edge;

typedef struct Node {
int from;
long long dis;
Node(){};
Node(int f,long long d):from(f),dis(d){};
}Node;

const int MAXN = 200100;
const long long INF = 0x7f7f7f7f7f7f7f7fLL;

bool vis[MAXN];
Edge edge[MAXN];
Edge head[MAXN];
long long dis[MAXN];
int val[MAXN];
int total,n,m;

void init();
void add_edge(int from,int to,int dis);
void dijkstra(int src);
bool operator < (const Node &a,const Node &b);

int main(int argc,char * argv[]) {
int i,j,k;
int x,y,z;
int Case,flag;
long long ans;
scanf("%d",&Case);
while (Case-->0) {
scanf("%d%d",&n,&m);
init();
for (i=1;i<=n;++i) scanf("%d",val+i);
for (i=1;i<=m;++i) {
scanf("%d%d%d",&x,&y,&z);
add_edge(x,y,z);
add_edge(y,x,z);
}
if (0 == n || 1 == n) {
printf("0\n");
continue;
}
if (0 == m) {
printf("No Answer\n");
continue;
}
dijkstra(1);
flag = 1;
ans = 0LL;
for (i=2;i<=n;++i) {
if (INF == dis[i]) {
flag = 0;
break;
}
ans += dis[i] * val[i];
}
if (!flag) {
printf("No Answer\n");
} else {
printf("%lld\n",ans);
}
}
return 0;
}

void dijkstra(int src) {
int p;
Node cur;
priority_queue<Node> pq;
memset(vis,0,sizeof(vis));
memset(dis,0x7f,sizeof(dis));
dis[src] = 0;
while (!pq.empty()) pq.pop();
pq.push(Node(src,0));
while (!pq.empty()) {
cur = pq.top();
pq.pop();
if (vis[cur.from]) continue;
vis[cur.from] = 1;
p = head[cur.from].next;
while (p) {
if (dis[edge[p].to] - edge[p].dis > dis[cur.from]) {
dis[edge[p].to] = dis[cur.from] + edge[p].dis;
pq.push(Node(edge[p].to,dis[edge[p].to]));
}
p = edge[p].next;
}
}
}

void init() {
total = 0;
for (int i=0;i<=n;++i)
head[i].next = 0;
}

void add_edge(int from,int to,int dis) {
++total;
edge[total].to = to;
edge[total].dis = dis;
edge[total].next = head[from].next;
head[from].next = total;
}

bool operator < (const Node &a,const Node &b) {
return a.dis > b.dis;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: