小C的闲逛_ssl1663_最短路

来源:互联网 发布:ubuntu安装twisted 编辑:程序博客网 时间:2024/05/19 23:10

Description


  小C一天来到一个游乐场,他打算在这个游乐场逛一逛。他不在乎有没有完全游览整个游乐场,他只是想对这个游乐场有个大体的了解。他很喜欢玩,很喜欢兜圈,他希望他能从某个地方出发,然后又回到这个地方,他称此为“闲逛”。但他不想浪费太多的时间,于是他找到了你。
题目说明
  游乐场可以看做是一个由N个点构成的图,它有M条单向通路。小C从i点到j点需要的时间为Ti,j。另外,由于游乐场刚刚建成,道路设置有些不合理,可能不能从任何一个地方出发然后回到那个地方,这时候输出“Impossible”,否则输出小C完成一次“闲逛”的最短时间,他可以从任何一个点出发。

Input


第一行两个整数N,M。接下来是M行,每行三个整数X,Y,T,表示X有一条通向Y的单向通路,小C走这条路需要的时间为T。

Output


如果小C无法完成“闲逛”,输出“Impossible”,否则输出最短的时间。

Analysis


枚举一条边删掉,找连接两点的最短路+边权就是环的长度
很暴力的做法不过太懒不优化了

Code


#include <cstring>#include <cstdio>#include <queue>#define N 101#define E N*(N-1)/2+1#define INF 0x7f7f7f7fusing namespace std;struct edge{int x,y,w,vis,next;}e[E];int dis[N],ls[E],maxE=0;bool vis[N];int min(int x,int y){return x<y?x:y;}void add(int x,int y,int w){e[++maxE]=(edge){x,y,w,0,ls[x]};ls[x]=maxE;}int spfa(int st,int ed){    for (int i=0;i<=N;i++)        dis[i]=1061109570;    memset(vis,false,sizeof(vis));    queue<int>q;    q.push(st);    dis[st]=0;    vis[st]=true;    while (!q.empty())    {        int now=q.front();q.pop();        for (int i=ls[now];i;i=e[i].next)            if (e[i].w+dis[now]<dis[e[i].y]&&!e[i].vis)            {                dis[e[i].y]=dis[now]+e[i].w;                if (!vis[e[i].y])                {                    vis[e[i].y]=true;                    q.push(e[i].y);                }            }        vis[now]=false;    }    return dis[ed];}int main(){    int n,m;    scanf("%d%d",&n,&m);    for (int i=1;i<=m;i++)    {        int x,y,w;        scanf("%d%d%d",&x,&y,&w);        add(x,y,w);    }    int ans=1061109570;    for (int i=1;i<=maxE;i++)    {        e[i].vis=1;        int tot=spfa(e[i].y,e[i].x)+e[i].w;        ans=min(ans,tot);        e[i].vis=0;    }    if (ans<1061109570)        printf("%d\n",ans);    else        printf("Impossible\n");    return 0;}
0 0
原创粉丝点击