Light OJ 1316 A Wedding Party 最短路+状态压缩DP

题目来源:Light OJ 1316 1316 - A Wedding Party

题意:和HDU 4284 差不多 有一些商店 从起点到终点在走过尽量多商店的情况下求最短路

思路:首先预处理每两点之前的最短路 然后只考虑那些商店 个数小于15嘛 就是TSP问题 状态压缩DP搞一下 状态压缩姿势不对 有必要加强

#include <cstdio>
#include <algorithm>
#include <queue>
#include <vector>
#include <cstring>
using namespace std;
const int maxn = 510;
const int maxm = 16;
const int INF = 999999999;
struct edge
{
    int u, v, w;
	edge(){}
	edge(int u, int v, int w): u(u), v(v), w(w) {}
};

struct HeapNode
{
    int u, dis;
    HeapNode(){};
    HeapNode(int u, int dis): u(u), dis(dis){};
    bool operator < (const HeapNode& rhs)const
    {
        return dis > rhs.dis;
    }
};
vector <edge> G[maxn];
int d[maxn][maxn];
int dp[1<<maxm][maxm];
bool vis[maxn];
int n, m, t;
int a[maxm];
void Dijkstra(int s)
{
    for(int i = 0; i <= n; i++)
   		d[s][i] = INF;
	d[s][s] = 0;
    memset(vis, false, sizeof(vis));
    priority_queue <HeapNode> Q;
    Q.push(HeapNode(s, 0));
    while(!Q.empty())
    {
        HeapNode x = Q.top();
        Q.pop();
        int u = x.u;
        if(vis[u])
            continue;
        vis[u] = true;
        for(int i = 0; i < G[u].size(); i++)
        {
            edge e = G[u][i];
            int v = e.v;
            if(d[s][v] > x.dis + e.w)
            {
                d[s][v] = x.dis + e.w;
                Q.push(HeapNode(v, d[s][v]));
            }
        }
    }
}
int get(int x)
{
	int ans = 0;
	while(x)
	{
		if(x&1)
			ans++;
		x >>= 1;
	}
	return ans;
}
int main()
{
	int T;
    int cas = 0;
    scanf("%d", &T);
    while(T--)
    {
    	scanf("%d %d %d", &n, &m, &t);
        for(int i = 0; i <= n; i++)
            G[i].clear();
        for(int i = 0; i < t; i++)
        {
        	int x;
        	scanf("%d", &x);
        	a[i] = x;
        }
        for(int i = 0; i < m; i++)
        {
            int u, v, w;
            scanf("%d %d %d", &u, &v, &w);
			G[u].push_back(edge(u, v, w));
        }
        for(int i = 0; i < n; i++)
 	 		Dijkstra(i);
	  	for(int s = 0; s < (1<<t); s++)
   		{
			for(int i = 0; i < t; i++)
 			{
        		dp[s][i] = INF;
				if(!(s&(1<<i)))
        			continue;
        		if(s == (1<<i))
       			{
       				//if(s == 2 && i == 1)
       				//	printf("%d\n", d[0][a[i]]);
 					dp[s][i] = d[0][a[i]];
 					continue;
       			}
       			for(int j = 0; j < t; j++)
       			{
       				if((s&(1<<j)) && (i != j))
       				{
       					if(dp[s^(1<<i)][j] == INF)
       						continue;
    					if(d[a[j]][a[i]] == INF)
							continue;
						//if(s == 3 && i == 0)
						//	printf("%d %d %d %d\n", dp[s^(1<<i)][j], d[a[j]][a[i]], j, dp[2][1]);
       					dp[s][i] = min(dp[s^(1<<i)][j] + d[a[j]][a[i]], dp[s][i]);
       				}
       			}

        	}
        }
        //printf("222*%d\n", dp[3][0]);
        int x;
        int ans = INF, sum = 0;
        for(int s = 1; s < (1<<t); s++)
        {

        	for(int i = 0; i < t; i++)
        	{
				//if(s == (1<<i))
        		//	printf("***%d %d %d\n", dp[s][i], i, s);
				//printf("**%d %d %d %d\n", dp[s][i], s, i, dp[2][i]);
				if(dp[s][i] == INF || d[a[i]][n-1] == INF)
        			continue;
        		int temp = get(s);
        		if(sum < temp || sum == temp && ans > dp[s][i]+d[a[i]][n-1])
        		{

        			sum = temp;
        			ans = dp[s][i]+d[a[i]][n-1];
        			x = s;
        		}
        	}
        }
        if(sum == 0)
        {
            printf("Case %d: Impossible\n", ++cas);
            continue;
        }
		printf("Case %d: %d %d\n", ++cas, sum, ans);
    }
    return 0;
}

Light OJ 1316 A Wedding Party 最短路+状态压缩DP

时间: 2024-10-04 10:13:34

Light OJ 1316 A Wedding Party 最短路+状态压缩DP的相关文章

Light OJ 1406 Assassin`s Creed 状态压缩DP+强连通缩点+最小路径覆盖

题目来源:Light OJ 1406 Assassin`s Creed 题意:有向图 派出最少的人经过全部的城市 而且每一个人不能走别人走过的地方 思路:最少的的人能够走全然图 明显是最小路径覆盖问题 这里可能有环 所以要缩点 可是看例子又发现 一个强连通分量可能要拆分 n最大才15 所以就状态压缩 将全图分成一个个子状态 每一个子状态缩点 求最小路径覆盖 这样就攻克了一个强连通分量拆分的问题 最后状态压缩DP求解最优值 #include <cstdio> #include <cstri

2010辽宁省赛E(Bellman_Ford最短路,状态压缩DP【三进制】)

#include<bits/stdc++.h>using namespace std;const int inf=0x3f3f3f3f;struct node{    int v,z,d,next;//存可以连接的点,用next存邻接表}a[10010];struct road{    int u,cnt,dis;//dis储存当前需要的钱数,即最短路算法里的权,u储存顶点,cnt储存组合数即状态压缩dp    road(int uu,int cntt,int diss)    {      

HDU Victor and World (最短路+状态压缩)

题目链接:传送门 题意: n个城市m条路.刚開始在点1,求把每一个城市都遍历一边最后回到1的花费的最小值. 分析: 我们首先须要预处理出随意两个国家之间的最短距离.由于数据范围非常小,所以直接用Floyd即可了.之后,我们用f[S][i]表示訪问国家的情况为S,当前最后訪问的一个国家是i所须要的最小总油量.当中.S的二进制表示记录了訪问国家的情况,S在二进制表示下的第i位(无论是从左往右还是从右往左都能够)假设是1则表示第i个国家被訪问过了,否则表示第i个国家没有被訪问过,那么f[S|(1<<

Light oj 1099 - Not the Best 次短路

题目大意:求次短路. 题目思路:由于可能存在重边的情况所以不能采用邻接矩阵储存图,我用了邻接表来存图. 由起点S到终点E的次短路可能由以下情况组成: 1.S到v点的次短路 + v到E的距离 2.S到v的最短路 +  v到E的距离 对于每个节点,我们分别采用dist1[],dist2[]储存起点到该节点最短路与次短路 次短路的更新条件应是:对于点u,在本轮松弛操作中若 当前的dist1[u]可以被更新,我们用d2来储存还未被更新的dist1[u]. 若满足:dist2[u]>d2 &&

Light OJ 1037 - Agent 47(预处理状态压缩DP)

题目大意: 有个特工要执行任务,他会遭遇到最多15个目标,特工必须把他们全部杀死.当他杀死一个目标后他可以使用目标的武器来杀死其他人.因此他必须有一个杀人的顺序,使得他开枪的次数最小. 现在给你一个表,代表每种武器对每个目标可以造成多少伤害.并且你知道每个目标的血量.当这个目标的血量小于等于0的时候说明这个目标被杀死了.最初的时候这个特工只有一个枪,这个枪可以对一个目标造成1点伤害. 题目分析: 先把每个状态下最敌人造成的伤害预处理出来,然后再进行一次记忆化搜索. ===============

Vijos1019 补丁VS错误[最短路 状态压缩]

描述 错误就是人们所说的Bug.用户在使用软件时总是希望其错误越少越好,最好是没有错误的.但是推出一个没有错误的软件几乎不可能,所以很多软件公司都在疯狂地发放补丁(有时这种补丁甚至是收费的).T公司就是其中之一. 上个月,T公司推出了一个新的字处理软件,随后发放了一批补丁.最近T公司发现其发放的补丁有致命的问题,那就是一个补丁在排除某些错误的同时,往往会加入另一些错误. 此字处理软件中只可能出现n个特定的错误,这n个错误是由软件本身决定的.T公司目前共发放了m个补丁,对于每一个补丁, 都有特定的

【上海交大oj】畅畅的牙签袋(状态压缩dp)

1383. 畅畅的牙签袋 题目描述 畅畅说:“你们都说窝脑子瓦特了,我看你们才是脑子瓦特嘞- -” 为了阻挠我们再次揭露他的无chǐ,畅畅妄图破坏我们的显示器,他拿出了自己收集的牙签包装袋,其大小是1×2的矩形,他想用密铺的方式把显示器全部遮挡住.显示器大小是W×H的矩形,畅畅把包装袋背面涂上了胶水,开始一块一块粘到显示器上,要求不能有包装袋重叠,也不能有显示器的某一部分没被遮挡,包装袋的放置只有两种情况:横放和竖放. 畅畅为自己的周密计划洋洋得意之时,脑子又瓦特了,他想让你帮他算算针对每台显示

【算法学习笔记】62.状态压缩 DP SJTU OJ 1088 邮递员小F

状态压缩,当我们的状态太多时可以考虑用bit来存储,用二进制来表示集合,用&来取交集,用^来异或. DP过程很简单,遍历所有情况取最短路径就行,因为最短哈密顿回路本身就是一个NPC问题,效率不高. #include <vector> #include <iostream> using namespace std; //最短哈密顿回路问题 NP完全问题... int map[16][16]={0}; int n=0; const int INF=768000;//3000*1

【上海交大oj】邮递员小F(状态压缩dp)(旅行商问题)

1088. 邮递员小F Description 因为制造类专业很难在大城市立足,曾经立志振兴中华之工业的小F,果断在本科毕业后转行做了一名光荣的邮递员. 他的任务是每天从总局出发,行走于所管辖区域的若干的邮局,收集所有的信,然后再汇总返回总局. 因为工作繁忙,同一个邮局他每天只希望去一次. 来往于任意两个邮局是有一定代价的.而且为了方便统计,假定来回两条道路上的代价假设是一样的. 现在小F希望你能给出他每天的最优行走方案,使得总的代价最少. Input Format 输入数据包括两部分. 第一行