Codeforces 545E Paths and Trees 题解

文章目录

题意

, , 使 u u . u , . 给一张边带权无向图,让你求一棵边权和最小的生成树,使得\newline 点u在树上到每个点的距离等于u在原图中到每个点的最短路.\newline 给出这张图和u,输出最小边权和以及构成这棵生成树的边集.

题解

大胆贪心,把每一个点相连的最短路上的边相加.
注意最短路算法中进行的松弛操作.
我们对经过每一个点的最短路上的边标记为 e i d v eid_v .
那么在跑最短路的时候,如果 d i s [ v ] > d i s [ u ] + c o s t dis[v]>dis[u]+cost ,那么 e i d [ v ] = i . i d eid[v]=i.id ,即这条边的编号.
如果 d i s [ v ] = d i s [ u ] + c o s t dis[v]=dis[u]+cost ,我们就贪心选较短的边.
这样下去除了起始点 u u 的所有点 v v e i d eid 组成的集合即为答案.

#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;
}

谢谢大家.

猜你喜欢

转载自blog.csdn.net/qq_31908675/article/details/83065177