hdu 4034 Graph(逆向floyd)

来源:互联网 发布:逻辑回归算法源码 编辑:程序博客网 时间:2024/05/20 05:10

floyd的松弛部分是 g[i][j] = min(g[i][j], g[i][k] + g[k][j]);也就是说,g[i][j] <= g[i][k] + g[k][j] (存在i->j, i->k, k->j的边)。

那么这个题很明显要逆向思考floyd算法。对于新图i,j,k,如果g[i][j] >  g[i][k] + g[k][j],那么肯定是不合理的。而如果g[i][j] =  g[i][k] + g[k][j],明显i->j的边可以删去。

//#pragma comment(linker, "/STACK:1024000000,1024000000")#include<algorithm>#include<iostream>#include<cstring>#include<fstream>#include<sstream>#include<vector>#include<string>#include<cstdio>#include<bitset>#include<queue>#include<stack>#include<cmath>#include<map>#include<set>#define FF(i, a, b) for(int i=a; i<b; i++)#define FD(i, a, b) for(int i=a; i>=b; i--)#define REP(i, n) for(int i=0; i<n; i++)#define CLR(a, b) memset(a, b, sizeof(a))#define debug puts("**debug**")#define LL long long#define PB push_back#define MP make_pair#define eps 1e-10using namespace std;const int maxn = 111;int vis[maxn][maxn], g[maxn][maxn];int n, T;int reFloyd(){    int ret = n*(n-1);    REP(k, n) REP(i, n) REP(j, n)    {        if(!vis[i][j] || !vis[i][k] || !vis[k][j]) continue;        else if(g[i][j] > g[i][k] + g[k][j]) return -1;        else if(g[i][j] == g[i][k] + g[k][j])        {            vis[i][j] = 0;            ret--;        }    }    return ret;}int main(){    scanf("%d", &T);    FF(kase, 1, T+1)    {        scanf("%d", &n);        REP(i, n) REP(j, n)        {            scanf("%d", &g[i][j]);            vis[i][j] = i == j ? 0 : 1;        }        printf("Case %d: ", kase);        int ans = reFloyd();        if(ans == -1) puts("impossible");        else printf("%d\n", ans);    }    return 0;}


原创粉丝点击