zoukankan      html  css  js  c++  java
  • hdu 4640 Island and study-sister(状态压缩dp)

    先处理前两个学长到达各个点所需要的最少时间,在计算前两个学长和最后一个学长救出所有学妹的最少时间。

    #include<stdio.h>
    #include<string.h>
    #include<vector>
    #include<algorithm>
    using namespace std;
    const int inf=1000000000;
    struct node{
    	int b,d;
    };
    struct node2{
        int dst,sta;
        node2(){}
        node2(int _dst,int _sta)
        {
            dst=_dst;sta=_sta;
        }
    }q[3000000];
    int dp[17][1<<17],n;
    int f[17],dis[1<<17],dis2[1<<17],s;
    vector<node>mp[17];
    void bfs()//建立所有状态
    {
        int i,j,k,st=0,ed=0,sta,dst,tmp;
        node2 p;
        node u;
        p.dst=1;p.sta=1;
        dp[1][1]=0;
        q[ed++]=p;
        while(st<ed)
        {
            p=q[st];
            dst=p.dst;
            sta=p.sta;
            for(i=0;i<mp[dst].size();i++)
            {
                u=mp[dst][i];tmp=sta|f[u.b];
    
                if(dp[u.b][tmp]>dp[dst][sta]+u.d)
                {
    
                    dp[u.b][tmp]=dp[dst][sta]+u.d;
                    q[ed++]=node2(u.b,tmp);
                }
            }
            st++;
        }
    }
    int main()
    {
    	int t,i,j,m,k,a,b,d,h,iter,juli,v=1,x;
    	f[1]=1;
    	for(i=2;i<=17;i++)f[i]=f[i-1]<<1;
    	node p;
    	scanf("%d",&t);
    	while(t--)
    	{
    		scanf("%d%d",&n,&m);
    		for(i=1;i<=n;i++)mp[i].clear();
    		for(i=1;i<=n;i++)
            for(j=0;j<1<<n;j++)
               dp[i][j]=inf;
    		while(m--)
    		{
    			scanf("%d%d%d",&a,&b,&d);
    			p.b=b;p.d=d;
    			mp[a].push_back(p);
    			p.b=a;
    			mp[b].push_back(p);
    		}
    		bfs();
    		for(i=1;i<1<<n;i+=2){//求出所有状态的最短时间
    			dis[i]=inf;
    		    for(j=1;j<=n;j++)
    		    	if(dp[j][i]<dis[i])
    		    		dis[i]=dp[j][i];
    		}
    		scanf("%d",&k);
    		int tmp=0;
    		for(i=0;i<k;i++)//目标状态
            {
                scanf("%d",&s);
                tmp|=f[s];
            }
            printf("Case %d: ",v++);
            int ans=inf;
            for(i=0;i<1<<n;i++)dis2[i]=inf;//两个学长一起
            for(i=0;i<1<<n;i++)
            for(h=j=i^((1<<n)-1);;j=h&(j-1)){
                if(dis2[i|j|1]>(x=max(dis[i|1],dis[j|1])))
                    dis2[i|j|1]=x;
                if(j==0)break;
            }
            for(i=0;i<1<<n;i++)//三个一起
            for(h=j=i^((1<<n)-1);;j=h&(j-1)){
                if(( ( (i|j|1)&tmp  )==tmp) && ans>(x=max(dis[i|1],dis2[j|1])))
                    ans=x;
                if(j==0)break;
            }
            if(ans==inf)ans=-1;
            printf("%d
    ",ans);
    	}
    	return 0;
    }
    


  • 相关阅读:
    第四周作业
    第三周作业
    第二周作业
    7-1,求最大值及下标值
    7-1.查找整数
    打印沙漏
    赚了还是亏了
    秋末学期总结
    机器学习小知识
    python 小知识
  • 原文地址:https://www.cnblogs.com/riskyer/p/3235590.html
Copyright © 2011-2022 走看看