做题记录整理图论/弗洛伊德 P1841 [JSOI2007] 重要的城市(2022/10/19)

P1841 [JSOI2007] 重要的城市
首先,一眼弗洛伊德
然后分析一下题目的性质,当一个点到另一个点的路径有两条以上时,它们这条路径是不会对答案产生贡献的(即使路径上是有点是重要的点,也早就在来的时候被记录过了),同时即使只有一条路径它们也只会给答案产生最多1的贡献(即使一路上都是重要的点,它们也都被记录过了,只有终点的前一个点没有被记录),所以我们就直接用一个数组来记录每个点到另一个点的产生的贡献就可以了

#include<bits/stdc++.h>
#define for1(i,a,b) for(int i = a;i<=b;i++)
#define ll long long
#define mp(a,b) make_pair(a,b)
using namespace std;
int dis[205][205],city[205][205],m,n;
bool ans[205],kg;
int main()
{
    cin>>n>>m;    
    for1(i,1,n)
        for1(j,1,n)
           if(i!=j)
                dis[i][j]=1e9;
    int x,y,z;
    for1(i,1,m)
    {
        cin>>x>>y>>z;
        dis[x][y]=z;
		dis[y][x]=z;
    }
    for1(k,1,n)
        for1(i,1,n)
            if(i!=k)
                for1(j,1,n)
                    if(i!=j&&j!=k)
                    {
                        if(dis[i][j]>dis[i][k]+dis[k][j])
                        {
                            dis[i][j]=dis[i][k]+dis[k][j];
                            city[i][j]=k;
                        }
                        else if(dis[i][j]==dis[i][k]+dis[k][j])
                            city[i][j]=-1;
                    }
    for1(i,1,n)
        for1(j,1,n)
            if(city[i][j]!=-1)
                ans[city[i][j]]=1;    
    for1(i,1,n)
        if(ans[i]==1) 
            cout<<i<<' ',kg=1;
    if(!kg)
        cout<<"No important cities.";
    return 0;
}
posted @ 2022-10-19 15:42  yyx525jia  阅读(26)  评论(0)    收藏  举报