社区讨论

蒟蒻求hack!

P1841[JSOI2007] 重要的城市参与者 2已保存回复 4

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
4 条
当前快照
1 份
快照标识符
@mi6y9qet
此快照首次捕获于
2025/11/20 12:47
4 个月前
此快照最后确认于
2025/11/20 12:47
4 个月前
查看原帖
我的辣鸡思路是先跑一遍floyd,然后算出任意两点间的最短路条数(如P1608路径统计所说),然后枚举城市i,若存在城市j、k,使i在j到k的某条最短路上且(j到i的最短路条数)×(i到k的最短路条数)==(j到k的最短路条数)则i为重要城市。
结果WA了第3、5、7点。请问大佬能否hack掉我的思路,或hack我的程序实现?
code:
CPP
#include <iostream>
#include <string.h>
#include <math.h>
#include <stdio.h>
#include <algorithm>
using namespace std;
typedef long long LL;
const int MAX=203;
const int inf=0x3f3f3f3f;
struct Graph
{
    struct Edge{int to,nxt;}e[MAX*(MAX-1)];
    int head[MAX],tot,n;
    void reset()
    {
        memset(head,-1,sizeof(head));
        tot=-1;n=-1;
    }
    Graph(){reset();}
    void addedge(int fr,int to)
    {
        e[++tot].to=to,e[tot].nxt=head[fr],head[fr]=tot;
        n=max(n,max(fr,to));
    }
    void addtwo(int u,int v){addedge(u,v),addedge(v,u);}
};//链式前向星
Graph gr;
int n,m;
int sp[MAX][MAX];//两点间最短路长度
LL cnt[MAX][MAX];//两点间最短路条数
void floyd()
{
    for(int k=1;k<=n;++k)
        for(int i=1;i<=n;++i)
            for(int j=1;j<=n;++j)
            {
                sp[i][j]=min(sp[i][j],sp[i][k]+sp[k][j]);
            }
}
inline bool onsp(int now,int u,int v)//now是否在u至v的某条最短路上
{
    return (sp[u][now]+sp[now][v]==sp[u][v]);
}
void dfs(int st,int en)//记搜最短路计数,求cnt[st][en]
{
    if(cnt[st][en]>0)return;
    for(int i=gr.head[st];i!=-1;i=gr.e[i].nxt)
    {
        int to=gr.e[i].to;
        if(onsp(to,st,en))
        {
            dfs(to,en);
            cnt[st][en]+=cnt[to][en];
        }
    }
}
void getcnt()
{
    for(int i=1;i<=n;++i)cnt[i][i]=1;
    for(int i=1;i<=n;++i)
    {
        for(int j=1;j<=n;++j)
        {
            if(i==j)continue;
            dfs(i,j);
        }
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    memset(sp,inf,sizeof(sp));
    for(int i=1;i<=n;i++)sp[i][i]=0;
    for(int i=1;i<=m;++i)
    {
        int u,v,l;
        scanf("%d%d%d",&u,&v,&l);
        gr.addtwo(u,v);
        sp[u][v]=sp[v][u]=l;
    }
    floyd();
    getcnt();
    bool hav=0;
    for(int i=1;i<=n;++i)
    {
        bool ok=0;//i是否重要
        for(int j=1;j<=n;++j)
        {
            if(j==i)continue;
            for(int k=j+1;k<=n;++k)
            {
                if(k==i)continue;
                //若i在j到k的某条最短路上且(j到i的最短路条数)×(i到k的最短路条数)==(j到k的最短路条数)则i重要
                if(onsp(i,j,k)&&cnt[j][i]*cnt[i][k]==cnt[j][k])
                {
                    ok=1;
                    goto ed;
                }
            }
        }
        ed:
        if(ok==1)hav=1,printf("%d ",i);
    }
    if(hav==0)printf("No important cities.");
    printf("\n");
    return 0;
}

回复

4 条回复,欢迎继续交流。

正在加载回复...