牛客算法周周练16 Rinne Loves Dynamic Graph

我太菜了,这种题目对于我来说还是太难了,
题目链接
这个题目的规律应该很容易找到,在这里插入图片描述循环是3次一循环,然后是否你这样写了代码在这里插入图片描述我wa了6发才发现这样写是不对的,为什么呢?因为f(1)肯定是最大,其他的两个都是在1左右的数,那么就可能发生一些本应该可以用f(2)的地方就用了f(1)导致答案偏大,那么到底该怎么建图呢?那么我们可以把一条单向边分成三种情况,那么无向边就是6种情况了,考虑单向边,我们可以建立一条第一层(u,v+n,w1)的边,(第二层u+n,v+2n,w2),第三层(u+2n,v,w3)(循环回到第一场),然后跑一次dij,取dis[n],dis[2n],dis[3n]的最小值即为最小值

#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<string>
#include<vector>
#include<queue>
#include<algorithm>
#include<deque>
#include<map>
#include<stdlib.h>
#include<set>
#include<iomanip>
#include<stack>
#define ll long long
#define ms(a,b) memset(a,b,sizeof(a))
#define lowbit(x) x & -x
#define fi first
#define se second
#define bug cout<<"----acac----"<<endl
#define IOS ios::sync_with_stdio(false), cin.tie(0),cout.tie(0)
using namespace std;
const int maxn = 9e5 + 50;
const int maxm = 1.5e5+50;
const double eps = 1e-7;
const double inf = 0x3f3f3f3f;
const ll  lnf  = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;
const  double pi=3.141592653589;
struct node
{
    double val;
    int next,to;
} a[maxn<<1];
int cnt=0;
int head[maxn<<1];
double dis[maxn];
int vis[maxn];
int n,m;
void add(int u,int v,double w)
{
    a[cnt].to=v;
    a[cnt].val=w;
    a[cnt].next=head[u];
    head[u]=cnt++;
}
struct point
{
    int id;
    double val;
    point(int id,double val)
    {
        this->id=id;
        this->val=val;
    }
    bool operator<(const point&x)const
    {
        return val>x.val;
    }
};
void dij(int s)
{
    for(int i=1; i<=3*n; i++)
    {
        dis[i]=inf;
        vis[i]=0;
    }
    priority_queue<point>q;
    q.push(point{s,0.0});
    dis[s]=0.0;
    while(!q.empty())
    {
        int u=q.top().id;
        q.pop();
        if(vis[u])continue;
        vis[u]=1;
        for(int i=head[u]; ~i; i=a[i].next)
        {
            int v=a[i].to;
            double x=a[i].val;
            if(!vis[v]&&dis[v]>dis[u]+x)
            {
                dis[v]=dis[u]+x;
                q.push(point(v,dis[v]));
            }
        }
    }
}
int main()
{
    ms(head,-1);
    cnt=0;
    scanf("%d%d",&n,&m);
    for(int i=1; i<=m; i++)
    {
        int u,v;
        double w;
        scanf("%d%d%lf",&u,&v,&w);
        add(u,v+n,w);
        add(v,u+n,w);
        w=(1.0/(1.0-w));
        add(u+n,v+2*n,fabs(w));
        add(v+n,u+2*n,fabs(w));
        w=(1.0/(1.0-w));
        add(u+2*n,v,fabs(w));
        add(v+2*n,u,fabs(w));
    }
    dij(1);
    double ans=min(dis[n],min(dis[2*n],dis[3*n]));
    if(ans==inf)
    {
        printf("-1\n");
    }
    else
    {
        printf("%.3lf",ans);
    }
    return 0;
}






猜你喜欢

转载自blog.csdn.net/qcccc_/article/details/107498629