Codeforces#303-E-Paths and Treesg-最短回路+最小生成ツリー
2639 ワード
http://codeforces.com/contest/545/problem/E
題意:無方向図G、始点Uを与えて、1つのサブ図を探し当てることを求めて、【サブ図の中でUから各点までの最短ルートは原図と等しい】、求める 【すべてのエッジ権の和が最小】サブマップ
出力ウェイト値と+各エッジの番号(エッジは入力順に1からmまで)
構想:直接最短ルートを求めてdist[]配列を得る
そして
for (i=1;i<=n; i++)
{
//点iに接続されているすべてのエッジを巡り、エッジが1つ見つかれば 【始点からi点までのdistは変わらない】そして【辺権が元より小さい】は、サブマップの辺を更新します
}
最小の重み値とこの部分の複雑さO(m)を求めます
最短ルート(n+m)log(n)を求めます
総複雑度は(n+m)log(n)......
題意:無方向図G、始点Uを与えて、1つのサブ図を探し当てることを求めて、【サブ図の中でUから各点までの最短ルートは原図と等しい】、求める 【すべてのエッジ権の和が最小】サブマップ
出力ウェイト値と+各エッジの番号(エッジは入力順に1からmまで)
構想:直接最短ルートを求めてdist[]配列を得る
そして
for (i=1;i<=n; i++)
{
//点iに接続されているすべてのエッジを巡り、エッジが1つ見つかれば 【始点からi点までのdistは変わらない】そして【辺権が元より小さい】は、サブマップの辺を更新します
}
最小の重み値とこの部分の複雑さO(m)を求めます
最短ルート(n+m)log(n)を求めます
総複雑度は(n+m)log(n)......
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <vector>
using namespace std;
#define INF 9223372036854775807
const __int64 maxn = 300005;
struct EDGE
{
__int64 u;
__int64 x;__int64 v;
int id;
EDGE(){}
EDGE (__int64 uu,__int64 i,__int64 j,__int64 idd)
{
u=uu; x=i;v=j; id=idd;
}
bool operator < (const EDGE &b) const
{
return v>b.v;
}
};
vector <EDGE> tm[maxn];
vector <int> ans;
__int64 dist[maxn];
priority_queue<EDGE> que;
int main()
{
__int64 n,r,i,j;
__int64 a,b,c;
scanf("%I64d%I64d",&n,&r);
for (i=1;i<=n;i++)
dist[i]=INF;
for (i=1;i<=r;i++)
{
scanf("%I64d %I64d %I64d",&a,&b,&c);
tm[a].push_back(EDGE(a,b,c,i));
tm[b].push_back(EDGE(b,a,c,i));
}
__int64 st;
scanf("%I64d",&st);
dist[st]=0;
que.push(EDGE(st,st,0,-1));
__int64 minway;
__int64 minpoint;
// --------------------Dijkstra
while(!que.empty())
{
EDGE p=que.top();
que.pop();
minpoint=p.x;
minway=p.v;
// vis[minpoint]=1;// spfa(), vis queue push, , push, vis
for (i=0;i<tm[minpoint].size();i++)
{
__int64 x=tm[minpoint][i].x;
__int64 v=tm[minpoint][i].v;
if ( v+minway<dist[x] /*&&vis[x]!=1*/ )
{
dist[x]=v+minway;
que.push(EDGE(i,x,dist[x],-1)); //id=-1 id
}
}
}
//
__int64 sum=0;
for (i=1;i<=n;i++)
{
if (i==st) continue;
__int64 MIN=INF;
int min_EDGE_id;
for (j=0;j<tm[i].size();j++)
{
__int64 y=tm[i][j].x;
if (y==i) continue;
__int64 v=tm[i][j].v;
if (dist[i]==dist[y]+v&&v<MIN)
{
MIN=v;
min_EDGE_id=tm[i][j].id;
}
}
sum+=MIN;
ans.push_back(min_EDGE_id);
}
printf("%I64d
",sum);
for (i=0;i<ans.size();i++)
{
if (i!=0) printf(" ");
printf("%d",ans[i]);
}
printf("
");
return 0;
}