HDU5521 最短路,添加点

来源:互联网 发布:java 腾讯地图api接口 编辑:程序博客网 时间:2024/05/21 10:49

Inspire:将思路理清,将难点抛离出来,将问题抽象化,再思考解决方法。

Analysis:最短路问题,难在建图。如果用邻接矩阵,边太多了,而点的个数我们可以接受,仔细读题发现,给出的集合内的任意的两个点的距离都是一定的,于是每个集合构造一个新的点作为中转站,集合内的点都连接两条线到该点,进来再出去,为了防止/2得到浮点数,所以进边和出边的权值都是t,最后结果/2。然后spfa搜两遍最短路,每个点的最大值作为两人在该点约会所需的时间,所有点中最小值即答案。

Note:需要初始化的变量(如pre[]、dis[])以及标志标量(如visted[])等,都要及时清零(改变),并注意清零的位置放在哪。

//哪些变量需要初始化,需要在哪个位置初始化,莫忘!仔细检查!#include <iostream>#include <stdio.h>#include <queue>#include <set>#include <vector>#include <math.h>#include <algorithm>#include <string.h>using namespace std;typedef long long ll;const int maxn=(1e6+10);const ll MAXN=1e17;ll dis1[maxn];ll dis2[maxn];int n,m;int cnt=0;int cur_set;int pre[maxn];int visted[maxn];struct Edge{    int u,v,w;    int next;    Edge(int u,int v,int w){        this->u=u;this->v=v;this->w=w;    }    Edge(){}}edge[maxn<<1];void Add(int u,int v,int w){    edge[cnt]=Edge(u,v,w);    edge[cnt].next=pre[u];    pre[u]=cnt++;}void Spfa(int x,ll dis[]){    queue<int> que;    que.push(x);    visted[x]=1;    for(int i=1;i<=cur_set;i++){        dis[i]=MAXN;        visted[i]=0;    }    dis[x]=0;    while(!que.empty()){        int u=que.front();        que.pop();        visted[u]=0;        int v,w;        for(int i=pre[u];~i;i=edge[i].next){            v=edge[i].v;            w=edge[i].w;            if(dis[v]>dis[u]+w){               dis[v]=dis[u]+w;               if(!visted[v]){                    que.push(v);                    visted[v]=1;//不要忘啊!!               }            }        }    }}int main(){    int tt;    scanf("%d",&tt);    int kk=1;    int t,num,x;    while(tt--){        scanf("%d%d",&n,&m);        cur_set=n;        cnt=0;        memset(pre,-1,sizeof(pre));//要放在建图前,要全部初始化而不等cur_set        for(int i=1;i<=m;i++){            scanf("%d%d",&t,&num);            cur_set++;            for(int j=1;j<=num;j++){                scanf("%d",&x);                Add(x,cur_set,t);                Add(cur_set,x,t);            }        }        //错误位置:        //for(int i=1;i<=cur_set;i++){            //pre[i]=-1;           ///visted[i]=0; visted[i]放在这初始化就错了,因为两个dis[]       // }        Spfa(1,dis1);        Spfa(n,dis2);        vector<int> vec;        //set<int> sset;set存储速度好像不如用vector然后最后sort一下        ll minn=MAXN;        for(int i=1;i<=n;i++){            minn=min(minn,max(dis1[i],dis2[i]));        }        for(int i=1;i<=n;i++){            if(minn==max(dis1[i],dis2[i]))    vec.push_back(i);                //sset.insert(i);        }        if(minn==MAXN){            cout<<"Case #"<<kk++<<": "<<"Evil John"<<endl;        }        else{            cout<<"Case #"<<kk++<<": "<<minn/2<<endl;                      //用set时的输出:            /*            set<int>::iterator it=sset.begin();            cout<<*it;            it++;            for(;it!=sset.end();it++){                cout<<" "<<*it;            }            cout<<endl;            */                                    //另一种比较方便的写法:虽然比cout慢几百ms,但是在时限为几千ms的题来说问题不大            /*            sort(vec.begin(),vec.end());            for(int i=0;i<vec.size();i++){                printf("%d%c",vec[i],i==vec.size()-1?'\n':' ');            }            */            sort(vec.begin(),vec.end());            cout<<vec[0];            for(int i=1;i<vec.size();i++){                cout<<" "<<vec[i];            }            cout<<endl;        }    }}

0 0
原创粉丝点击