P1841 [JSOI2007] of the city's most important short-circuit

  

The same situation also appears in the traffic between cities. Some cities if a problem could cause a lot of inconvenience to traffic other cities. Other cities are not affect other traffic in the city. jsoi winter camp of the students found this to be an interesting question, and decided to study the problem.

They think this city is important: If a city is destroyed c, there are two different cities a and b (a, b not equal to c), a shortest distance b increased (or blocked), then c city is important.

jsoi students faced a winter camp coaching staff handed between their city traffic map, they hope to find all the important cities. Now ask you to solve this problem.

Input and output formats

Input formats:

 

The first line two integers N, M, N is the number of cities, M is the number of road

Next M rows, each row of three integers, no represents the length between the two sides of the city, and the path between the

 

Output formats:

 

Line, in ascending order of the number of output number represents an important city.

 

Sample input and output

Input Sample # 1:  Copy
4 4
1 2 1
2 3 1
4 1 2
4 3 2
Output Sample # 1:  Copy
2 

If you remove a point from the presence of any other two points bigger then that this is an important point output all the important points

with floyed very clever
#include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int INF=2e6;
    int e[205][205],city[205][205],m,n;
    bool ans[205],cs;
    int main()
    {
        cin>>n>>m;    
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                if(i!=j)
                    e[i][j]=INF;
        for(int i=1,x,y,u;i<=m;i++)
        {
            cin>>x>>y>>u;
            e[x][y]=e[y][x]=u;
        }
        for(int k=1;k<=n;k++)
            for(int i=1;i<=n;i++)
                if(i!=k)
                    for(int j=1;j<=n;j++)
                        if(i!=j&&j!=k)
                        {
                            if(e[i][j]>e[i][k]+e[k][j])
                            {
                                e[i][j]=e[i][k]+e[k][j];
                                city[i][j]=k;
                            }
                            else if(e[i][j]==e[i][k]+e[k][j])
                                city[i][j]=-1;
                        }
        for(int i=1;i<=n;i++) 
            for(int j=1;j<=n;j++)
                if(city[i][j]!=-1)
                    ans[city[i][j]]=true;    
        for(int i=1;i<=n;i++)
            if(ans[i])
                cout<<i<<' ',cs=true;
        if(!cs)
            cout<<"No important cities.";
        return 0;
    }
View Code

 

Another way spfa enumeration starting point of use:

A city x important, if and only if after removing it allows s-> t change the shortest path (s! = T! = X). N Because this question is very small, we can enumerate n as s.

After determining s, s is the starting point of a shortest run, then all the edges in the shortest way to add a new image. Specifically: For an edge, if it is at the start of the shortest plus side the right to equal shortest at the end, then put it to a new figure.

The new plan has a nice nature: it is a DAG. The reason is simple, do not ring the shortest path = =. Note that this shortest DAG records the shortest s as a starting point to all points.

Enumeration of 1 to n for each point. If there is an edge x-> y, and y is the degree of 1, then y is deleted after x-degree becomes 0, obviously can not reach from s, destroy some of the most short-circuit point that is deleted after x. x is a critical point. (A word find all the shortest of 1 if the point is that from the major cities)

#include <bits/stdc++.h>
using namespace std;

inline int rd() {
    int a = 1, b = 0; char c = getchar();
    while (!isdigit(c)) a = c == '-' ? 0 : 1, c = getchar();
    while (isdigit(c)) b = b * 10 + c - '0', c = getchar();
    return a ? b : -b;
}

const int N = 500, M = N * N;
struct Graph {
    int from, to, nxt, c;
} g[M * 2];
int head[N], tot;

void addedge(int x, int y, int c) {
    g[++tot].to = y, g[tot].from = x, g[tot].c = c,
    g[tot].nxt = head[x], head[x] = tot;
}

int n, m;

priority_queue<pair<int, int> > que;
int dis[N], in[N];
bool vis[N], important[N], mark[M];

void solve(int s) {
    memset(dis, 0x3f, sizeof(dis));
    memset(vis, 0, sizeof(vis));
    dis[s] = 0;
    que.push(make_pair(0, s));
    while (!que.empty()) {
        int x = que.top().second;
        que.pop();
        if (!vis[x]) {
            vis[x] = true;
            for (int i = head[x]; i; i = g[i].nxt) {
                int y = g[i].to;
                if (dis[y] > dis[x] + g[i].c) {
                    dis[y] = dis[x] + g[i].c;
                    que.push(make_pair(-dis[y], y));
                }
            }
        }
    }

    memset(mark, 0, sizeof(mark));
    memset(in, 0, sizeof(in));
    for (int i = 1; i <= tot; ++i) {
        if (dis[g[i].from] + g[i].c == dis[g[i].to]) {
            mark[i] = true;
            printf("from=%d v=%d to=%d\n",g[i].from,g[i].c,g[i].to);
            ++in[g[i].to];
        }
    }

    for (int i = 1; i <= tot; ++i)
        if (mark[i] && in[g[i].to] == 1 && g[i].from != s)
            important[g[i].from] = true;
}

int main() {
    n = rd(), m = rd();
    for (int i = 1; i <= m; ++i) {
        int x = rd(), y = rd(), c = rd();
        addedge(x, y, c), addedge(y, x, c);
    }

        solve(1);
    bool ok = false;
    for (int i = 1; i <= n; ++i)
        if (important[i]) {
            cout << i << " ";
            ok = true;
        }
    if (!ok) cout << "No important cities.";
    cout << endl;
    return 0;
}
View Code

 






Guess you like

Origin www.cnblogs.com/bxd123/p/10963279.html