poj1511(最小环和)

题目连接:http://poj.org/bbs?problem_id=1511

求1到各点再回到1的最短路之和。

数据太大,只能用spfa??

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<queue>
 4 #include<stack>
 5 using namespace std;
 6 #define ll long long
 7 const int maxn=1000010;
 8 const int inf=0x3f3f3f3f;
 9 int head[maxn];
10 int inq[maxn];
11 ll dis[maxn];
12 int n,m,t;
13 int u,v,w;
14 struct node
15 {
16     int u,v,w;
17     int nex;
18 }e[maxn],tmp[maxn];
19 int cnt;
20 
21 void add(int u,int v,int w)
22 {
23     e[cnt].u=u;
24     e[cnt].v=v;
25     e[cnt].w=w;
26     e[cnt].nex=head[u];
27     head[u]=cnt++;
28 }
29 ll spfa()
30 {
31     stack<int>q;
32     for(int i=1;i<=n;i++)
33     {
34         inq[i]=0;
35         dis[i]=inf;
36     }
37     dis[1]=0;
38     inq[1]=1;
39     q.push(1);
40     while(!q.empty())
41     {
42         int x=q.top();
43         q.pop();
44         inq[x]=0;
45         for(int i=head[x];i!=-1;i=e[i].nex)
46         {
47             if(dis[e[i].v]>dis[x]+e[i].w)
48             {
49                 dis[e[i].v]=dis[x]+e[i].w;
50                 if(!inq[e[i].v])
51                 {
52                     q.push(e[i].v);
53                     inq[e[i].v]=1;
54                 }
55             }
56         }
57     }
58     ll res=0;
59     for(int i=1;i<=n;i++)
60         res+=dis[i];
61     return res;
62 }
63 int main()
64 {
65     scanf("%d",&t);
66     while(t--)
67     {
68         cnt=0;
69         scanf("%d%d",&n,&m);
70         memset(head,-1,sizeof(head));
71         for(int i=0;i<m;i++)
72         {
73             scanf("%d%d%d",&tmp[i].u,&tmp[i].v,&tmp[i].w);
74             add(tmp[i].u,tmp[i].v,tmp[i].w);
75         }
76         ll s1=spfa();
77         memset(head,-1,sizeof(head));
78         cnt=0;
79         for(int i=0;i<m;i++)
80             add(tmp[i].v,tmp[i].u,tmp[i].w);
81          ll s2=spfa();
82          printf("%lld\n",s1+s2);
83 
84 
85     }
86 }

 

posted @ 2017-04-20 08:45  yijiull  阅读(101)  评论(0编辑  收藏  举报