UVA 12437 Kisu Pari Na 2

来源:互联网 发布:易语言编程教学 编辑:程序博客网 时间:2024/04/30 11:44

无向图经过K个顶点的最少花费,每条路的权值相等均为1


# include <stdio.h># include <string.h># include <algorithm># include <vector>using namespace std;const int MAXN=1e4+10;const int INF=1e7;vector<int>vec[MAXN];int vis[MAXN];int ans[MAXN],num,longest,ending;void dfs (int u,int fa,int deep){    num++;    vis[u]=1;    if(deep>longest)    {        longest=deep;        ending=u; //记录最长链的结束顶点    }    for(int i=0;i<vec[u].size();i++)    {        int v=vec[u][i];        if(v!=fa)        {            dfs(v,u,deep+1);        }    }}void solve (int k) //num记录从k出发可以到达的点的个数,longest记录路径中最长的链的长度{    num=0;    longest=0;    dfs(k,-1,1);    longest=0;    num=0;    dfs(ending,-1,1); //两遍dfs保证所找的链是当前连通图中最长的,第二遍主要是更新longest,num实际上是不变的    for(int i=1;i<=longest;i++)    {        ans[i]=min(ans[i],i-1);    }    for(int i=longest+1;i<=num;i++)    {        ans[i]=min(ans[i],2*i-longest-1);    }}int main (){    int t,n,m,u,v,k,q;    scanf("%d",&t);    for(int ca=1;ca<=t;ca++)    {        scanf("%d%d",&n,&m);        for(int i=1;i<=n;i++) vec[i].clear();        for(int i=1;i<=m;i++)        {            scanf("%d%d",&u,&v);            vec[u].push_back(v);            vec[v].push_back(u);        }        memset(vis,0,sizeof(vis));        for(int i=1;i<=MAXN;i++)        {            ans[i]=INF;        }        for(int i=1;i<=n;i++)        {            if(!vis[i]) solve(i); //相当于在每一个连通分量中更新最少花费的值        }        scanf("%d",&k);        printf("Case %d:\n",ca);        while(k--)        {            scanf("%d",&q);            if(ans[q]==INF) printf("impossible\n");            else printf("%d\n",ans[q]);        }    }    return 0;}


0 0
原创粉丝点击