[kuangbin带你飞]专题四 最短路练习H,I,J

来源:互联网 发布:潮汕话学习软件 编辑:程序博客网 时间:2024/06/11 17:03

H题:
http://poj.org/problem?id=3660

题意:

给你n个点,m个关系,每个关系说明了u在v前
问能确定下来位置的点有多少

tip:

首先能想到一个点的前面+后面= n-1就是确定位置,那怎么知道呢?
dfs啊。。。。但是这个貌似是最短路专题QAQ,那就Floyd,floyd本身的想法就是用一个中间点更新两边点的关系,这个题也是一样,前驱的前驱一定是前驱,找到所有这样的就好啦

#include <cstdio>#include <iostream>#include <cstring>using namespace std;const int maxn = 120;int n,m,map[maxn][maxn];void init(){    memset(map,0,sizeof(map));    for(int i = 0 ; i < m ; i++){        int u,v;        scanf("%d%d",&u,&v);        map[u][v] = 1;    }}void floyd(){    for(int i = 1 ; i <= n ; i++)        for(int j = 1; j <= n ; j++)            for(int k = 1; k <= n ;k++)                if(map[j][i] == 1 &&map[i][k] == 1)                    map[j][k] = 1;}void sov(){    int cnt = 0;    for(int i = 1; i <= n ; i++){        int ans = 0;        for(int j = 1; j <= n ;j++){            if(i==j)continue;            if(map[i][j] == 1 || map[j][i] == 1)    ans++;        }        if(ans == n-1)  cnt++;    }    printf("%d\n",cnt);}int main(){    while(~scanf("%d%d",&n,&m)){        init();        floyd();        sov();    }}

I题和之前一样。。。

#include <iostream>#include <string.h>#include <cstdio>using namespace std;#define MAXC 100#define MAXV 50double map[MAXV][MAXV];int n,m;void Input(){    char s[MAXV][MAXC],a[MAXC],b[MAXC];    int i,k,j;    double c;    for(i=0;i<=n;i++)        for(j=0;j<=n;j++)            if(i==j)                map[i][j]=1;            else                map[i][i]=0;    for(i=1;i<=n;i++) scanf("%s",s[i]);    scanf("%d\n",&m);    for(i=1;i<=m;i++){        scanf("%s %lf %s",a,&c,b);        for(j=1;j<=n;j++)            if(!strcmp(s[j],a)) break;        for(k=1;k<=n;k++)            if(!strcmp(s[k],b)) break;        map[j][k]=c;    }}void floyd(){    int i,j,k;    for(k=1;k<=n;k++)        for(i=1;i<=n;i++)            for(j=1;j<=n;j++)                if(map[i][k]*map[k][j]>map[i][j])                    map[i][j]=map[i][k]*map[k][j];}int main(){    int cas=1,i;    while(scanf("%d\n",&n) && n){        Input();        floyd();        printf("Case %d: ",cas++);        for(i=1;i<=n;i++)            if(map[i][i]>1) break;        if(i>n) printf("No\n");        else printf("Yes\n");    }    return 0;}

J

反向图再来一次

#include <cstdio>#include <iostream>#include <queue>using namespace std;#define MAXM 1000010#define INF 0xFFFFFFFFstruct{    int e,next,w;}edge[2][MAXM];__int64 d[MAXM],ans;int n,m,headlist[2][MAXM],vis[MAXM];void spfa(int cap){    int v,i,b;    queue <int>q;    for(i=1;i<=n;i++){        d[i]=INF;        vis[i]=0;    }    q.push(1);    vis[1]=1;    d[1]=0;    while(!q.empty()){        v=q.front();        q.pop();        vis[v]=0;        for(i=headlist[cap][v];i!=-1;i=edge[cap][i].next){            b=edge[cap][i].e;            if(d[b]>d[v]+edge[cap][i].w){                d[b]=d[v]+edge[cap][i].w;                if(!vis[b]){                    vis[b]=1;                    q.push(b);                }            }        }    }}int main(){    int t,i,a,b,w;    scanf("%d",&t);    while(t--){        scanf("%d%d",&n,&m);        for(i=1;i<=n;i++){            headlist[0][i]=-1;            headlist[1][i]=-1;        }        for(i=0;i<m;i++){            scanf("%d%d%d",&a,&b,&w);            edge[0][i].w=w;            edge[0][i].e=b;            edge[0][i].next=headlist[0][a];            headlist[0][a]=i;            edge[1][i].w=w;            edge[1][i].e=a;            edge[1][i].next=headlist[1][b];            headlist[1][b]=i;        }        ans=0;        spfa(0);        for(i=1;i<=n;i++) ans+=d[i];        spfa(1);        for(i=1;i<=n;i++) ans+=d[i];        printf("%I64d\n",ans);    }    return 0;}
0 0
原创粉丝点击