题目描述有误/或警示后人
  • 板块P1491 集合位置
  • 楼主Mo20
  • 当前回复1
  • 已保存回复1
  • 发布时间2023/12/6 16:47
  • 上次更新2023/12/6 19:48:28
查看原帖
题目描述有误/或警示后人
448983
Mo20楼主2023/12/6 16:47

题目描述中 pi,qip_i,q_i 联通应表述为 pi,qip_i,q_i 中存在一条无向边,联通表示的是这两个点间存在且仅存在一条边(个人理解),因为显然你重复表述两次同一对联通也不会改变其只有一条边的现状

这是 AC 代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=200010;
const int inf=0x3f3f3f3f;
inline int read()
{
    int x=0;int f=1;char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
    return ~f?x:-x;
}
struct point{int x,y;}p[maxn];
long double dist(int x,int y){return sqrt((p[x].x-p[y].x)*(p[x].x-p[y].x)+(p[x].y-p[y].y)*(p[x].y-p[y].y));}
struct node{bool flag;int to,nxt;long double w;}edge[maxn];
int head[maxn],tot=1;
map<pair<int,int>,int> id;
void add(int x,int y,long double w)
{
    // if(id.count({x,y})) return;
    id[{x,y}]=++tot;
    edge[tot].to=y;
    edge[tot].w=w;
    edge[tot].flag=1;
    edge[tot].nxt=head[x];
    head[x]=tot;
}
int n,m;
pair<int,long double> dis[maxn];bool vis[maxn];
long double spfa()
{
    queue<int> q;
    for(int i=1;i<=n;i++) {dis[i]=make_pair(-1,inf);vis[i]=0;}
    dis[1]=make_pair(-1,0.0);vis[1]=1;q.push(1);
    while(!q.empty())
    {
        int u=q.front();q.pop();
        vis[u]=0;
        for(int i=head[u];i;i=edge[i].nxt)
        {
            int v=edge[i].to;
            if(!edge[i].flag) continue;
            if(dis[v].second>dis[u].second+edge[i].w)
            {
                dis[v]=make_pair(u,dis[u].second+edge[i].w);
                if(!vis[v]) {vis[v]=1;q.push(v);}
            }
        }   
    }
    return dis[n].second;
}
vector<int> edge_del;
int main()
{
    n=read();m=read();
    for(int i=1;i<=n;i++) {p[i].x=read();p[i].y=read();}
    for(int i=1,x,y;i<=m;i++)
    {
        x=read();y=read();
        add(x,y,dist(x,y));
        add(y,x,dist(x,y));
    }
    long double Max=spfa();
    for(int u=n;~u;) {int v=dis[u].first;if(v>=1&&u>=1) edge_del.push_back(id[{u,v}]);u=v;}
    long double ans=inf;
    // cout<<edge_del.size()<<endl<<endl;
    for(int i:edge_del)
    {
        edge[i].flag=edge[i^1].flag=0;
        ans=min(ans,spfa());
        edge[i].flag=edge[i^1].flag=1;
    }
    ans==inf?puts("-1"):printf("%.2Lf\n",ans);
    return 0;
}

这是 WAon #4,#5,#6

#include<bits/stdc++.h>
using namespace std;
const int maxn=200010;
const int inf=0x3f3f3f3f;
inline int read()
{
    int x=0;int f=1;char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
    return ~f?x:-x;
}
struct point{int x,y;}p[maxn];
long double dist(int x,int y){return sqrt((p[x].x-p[y].x)*(p[x].x-p[y].x)+(p[x].y-p[y].y)*(p[x].y-p[y].y));}
struct node{bool flag;int to,nxt;long double w;}edge[maxn];
int head[maxn],tot=1;
map<pair<int,int>,int> id;
void add(int x,int y,long double w)
{
    if(id.count({x,y})) return;
    id[{x,y}]=++tot;
    edge[tot].to=y;
    edge[tot].w=w;
    edge[tot].flag=1;
    edge[tot].nxt=head[x];
    head[x]=tot;
}
int n,m;
pair<int,long double> dis[maxn];bool vis[maxn];
long double spfa()
{
    queue<int> q;
    for(int i=1;i<=n;i++) {dis[i]=make_pair(-1,inf);vis[i]=0;}
    dis[1]=make_pair(-1,0.0);vis[1]=1;q.push(1);
    while(!q.empty())
    {
        int u=q.front();q.pop();
        vis[u]=0;
        for(int i=head[u];i;i=edge[i].nxt)
        {
            int v=edge[i].to;
            if(!edge[i].flag) continue;
            if(dis[v].second>dis[u].second+edge[i].w)
            {
                dis[v]=make_pair(u,dis[u].second+edge[i].w);
                if(!vis[v]) {vis[v]=1;q.push(v);}
            }
        }   
    }
    return dis[n].second;
}
vector<int> edge_del;
int main()
{
    n=read();m=read();
    for(int i=1;i<=n;i++) {p[i].x=read();p[i].y=read();}
    for(int i=1,x,y;i<=m;i++)
    {
        x=read();y=read();
        add(x,y,dist(x,y));
        add(y,x,dist(x,y));
    }
    long double Max=spfa();
    for(int u=n;~u;) {int v=dis[u].first;if(v>=1&&u>=1) edge_del.push_back(id[{u,v}]);u=v;}
    long double ans=inf;
    // cout<<edge_del.size()<<endl<<endl;
    for(int i:edge_del)
    {
        edge[i].flag=edge[i^1].flag=0;
        ans=min(ans,spfa());
        edge[i].flag=edge[i^1].flag=1;
    }
    ans==inf?puts("-1"):printf("%.2Lf\n",ans);
    return 0;
}
2023/12/6 16:47
加载中...