Codeforces 545E Paths and Trees 題解
阿新 • • 發佈:2018-11-10
文章目錄
題意
題解
大膽貪心,把每一個點相連的最短路上的邊相加.
注意最短路演算法中進行的鬆弛操作.
我們對經過每一個點的最短路上的邊標記為
.
那麼在跑最短路的時候,如果
,那麼
,即這條邊的編號.
如果
,我們就貪心選較短的邊.
這樣下去除了起始點
的所有點
的
組成的集合即為答案.
#include<bits/stdc++.h> //Ithea Myse Valgulious
namespace chtholly{
typedef long long ll;
#define re0 register int
#define rel register ll
#define rec register char
#define gc getchar
//#define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<23,stdin),p1==p2)?-1:*p1++)
#define pc putchar
#define p32 pc(' ')
#define pl puts("")
/*By Citrus*/
char buf[1<<23],*p1=buf,*p2=buf;
inline int read(){
int x=0,f=1;char c=gc();
for (;!isdigit(c);c=gc()) f^=c=='-';
for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');
return f?x:-x;
}
template <typename mitsuha>
inline bool read(mitsuha &x){
x=0;int f=1;char c=gc();
for (;!isdigit(c)&&~c;c=gc()) f^=c=='-';
if (!~c) return 0;
for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');
return x=f?x:-x,1;
}
template <typename mitsuha>
inline int write(mitsuha x){
if (!x) return 0&pc(48);
if (x<0) pc('-'),x=-x;
int bit[20],i,p=0;
for (;x;x/=10) bit[++p]=x%10;
for (i=p;i;--i) pc(bit[i]+48);
return 0;
}
inline char fuhao(){
char c=gc();
for (;isspace(c);c=gc());
return c;
}
}using namespace chtholly;
using namespace std;
const int yuzu=3e5,inf=0x3f3f3f3f;
typedef int fuko[yuzu|10];
typedef ll rize[yuzu|10];
struct edge{int to,cost,id;}e[yuzu|10];
vector<edge> lj[yuzu|10];
vector<int> ans;
namespace {
rize dis; fuko eid,vis;
void spfa(int s) {
memset(dis,0x3f,sizeof dis);
queue<int> q;
dis[s]=0,q.push(s);
for (;!q.empty();) {
int u=q.front(); q.pop();
vis[u]=0;
for (edge i:lj[u]) {
int v=i.to; ll c=i.cost;
if (dis[u]+c==dis[v]&&e[eid[v]].cost>c){
eid[v]=i.id;
if (!vis[v]) q.push(v),vis[v]=1;
}
if (dis[v]>dis[u]+c) {
dis[v]=dis[u]+c;
eid[v]=i.id;
if (!vis[v]) q.push(v),vis[v]=1;
}
}
}
}
}
int main() {
int i,n,m,u,v,c;
read(n),read(m);
for (i=1;i<=m;++i) {
read(u),read(v),read(c);
lj[u].push_back(edge{v,c,i});
lj[v].push_back(edge{u,c,i});
e[i]=edge{v,c,i};
}
e->cost=inf;
spfa(read());
ll llx=0;
for (i=1;i<=n;++i) if (eid[i]) ans.push_back(eid[i]),llx+=e[eid[i]].cost;
cout<<llx<<endl;
for (auto p:ans) write(p),p32;
}
謝謝大家.