保留道路

来源:互联网 发布:淘宝订单险 编辑:程序博客网 时间:2024/05/01 20:23

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
将边排序,以g为第一关键字,s为第二关键字
每次枚举一个maxg,将g

if(a[i].s+a[i].g>ans) continue;

如果当前ans<当前加入的边的g+s,那么这条边对于ans无任何贡献(因为在边集中的边的s的最大值(加入此边后)一定>=当前S),那么这些边生成的最小生成树所得出ans一定比当前ans大,无意义
不加60,加了AC

#include <cstdio>#include <iostream>#include <algorithm>using namespace std;struct node{    int x,y;    long long g,s;    bool vis;}a[510000];node now_tree[520000],tree[510000];int fat[510000];int n,m,max_g,max_s,cnt;long long ans=1e17;inline int read(){    int data=0,w=1; char ch=0;    while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();    if(ch=='-') w=-1,ch=getchar();    while(ch>='0' && ch<='9') data=data*10+ch-'0',ch=getchar();    return data*w;}bool comp(const node&s1,const node&s2){    if(s1.g!=s2.g) return s1.g<s2.g;    return s1.s<s2.s;}int find(int x){    if(fat[x]==x) return x;    return fat[x]=find(fat[x]);}void init(){    for(int i=1;i<=n;i++)     fat[i]=i;    for(int i=1;i<=cnt;i++)     now_tree[i]=tree[i],now_tree[i].vis=0;}void get_ans(long long maxg){    long long maxs=0;    long long tot=0;    init();    for(int i=1;i<=cnt;i++)     {        int f1=find(tree[i].x),f2=find(tree[i].y);        if(f1!=f2)        {            tot++;            fat[f1]=f2;            now_tree[i].vis=1;            maxs=max(maxs,tree[i].s);        }        if(tot==n-1)        {            int sum=0;            for(int j=1;j<=cnt;j++)             if(now_tree[j].vis) tree[++sum]=now_tree[j];            cnt=sum;            ans=min(ans,maxs+maxg);            break;        }     }     return;}int main(){    freopen("road.in","r",stdin);    freopen("road.out","w",stdout);    scanf("%d%d%d%d",&n,&m,&max_g,&max_s);    for(int i=1,g,s;i<=m;i++)    {        a[i].x=read(),a[i].y=read();        g=read(),s=read();        a[i].g=(long long)g*max_g,a[i].s=(long long)s*max_s;    }    sort(a+1,a+m+1,comp);    int flag=0;    for(int i=1;i<=m;i++)     {        if(a[i].s+a[i].g>ans) continue;        int w=cnt+1;        for(int j=1;j<=cnt;j++)         if(tree[j].s>a[i].s)          {            w=j;            break;          }         if(w==cnt+1) tree[++cnt]=a[i];        else        {          cnt++;          for(int j=cnt;j>=w+1;j--)           tree[j]=tree[j-1];          tree[w]=a[i];        }        get_ans(a[i].g);     }      if(ans!=1e16)      printf("%lld",ans);     else     printf("-1");}
原创粉丝点击