cf1204C. Anna, Svyatoslav and Maps(给一段邻间皆连边的路径,可删多少点使得最短路径不变)

题目
题意: 给一段abcdefab…路径,保证相邻的两个点一定有直接边相连。问你可以最多删掉多少点,使得 给定路径也可以作为 要想经过删后的所有点的最短路径。
思路: abcde 假如dis(a,b)+dis(b,c)=dis(a,c)。d这个点一定要删掉。因为此时ac之间经过d也是最短的。假如dis(a,c)+dis(c,d)>dis(a,d). c这个点一定要删掉。。显而易见。

哦对刚开始N=100,第九个样例n=99,我一直t 9。很奇怪呜呜。

#include<bits/stdc++.h>
using namespace std;
const int N=100+5,M=1e6+6;
int ma[N][N],p[M],ans[M];
char s[N];
int main(){
    int n;scanf("%d",&n);
    for(int i=1;i<=n;++i){
        scanf("%s",s+1);
        for(int j=1;j<=n;++j) (s[j]=='1')?ma[i][j]=1:ma[i][j]=101;
        ma[i][i]=0;
    }
    for(int k=1;k<=n;++k)
        for(int i=1;i<=n;++i)
                for(int j=1;j<=n;++j)
                    if(ma[i][j]>ma[i][k]+ma[k][j]) ma[i][j]=ma[i][k]+ma[k][j];
    int m;scanf("%d",&m);
    for(int i=1;i<=m;++i) scanf("%d",&p[i]);
    int num=0;ans[++num]=p[1];
    for(int pre=1,las;pre<m;pre=las){
        las=pre+2;
        while(las<=m&&ma[p[pre]][p[las]]==ma[p[pre]][p[las-1]]+ma[p[las-1]][p[las]]) ++las;
        ans[++num]=p[--las];
    }
    printf("%d\n",num);
    for(int i=1;i<=num;++i) printf("%d ",ans[i]);
}
©️2020 CSDN 皮肤主题: 终极编程指南 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值