UVa 658 It's not a Bug, it's a Feature! / SPFA

隐式图的最短路径 题目看了老久

要修复所有的漏洞 每个补丁需要一定条件才能打(第一个字符串 第i个字符是+ 说明当前状态一定要有第i个漏洞才能装 - 就是一定没有 o可有可无) 打了可能会导入 或者去掉漏洞(第二个字符串)

从1111(n个1)开始做SPFA 终点是00000(n个0)都用2进制表示

然后是否能使用补丁需要判断 用位运算处理

使用补丁后的状态用一个2进制表示

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;

struct node
{
	int time;
	int s1;
	int s2;
	int e1;
	int e2;
}a[110];

int n,m;
int dis[2000000];
bool vis[2000000];
void SPFA()
{
	int i;
	int s = (1 << n) - 1;
	for(i = 0;i < s; i++)
		dis[i] = 999999999;
	dis[s] = 0;
	memset(vis,false,sizeof(vis));
	queue <int> q;
	q.push(s);
	while(!q.empty())
	{
		int p = q.front();
		q.pop();
		vis[p] = false;
		for(i = 1;i <= m; i++)
		{
			int t1 = p | a[i].s1;
			int t2 = p & a[i].s2;
			if(t1 == p && t2 == p)
			{
				int t;
				t = p | a[i].e1;
				t = t & a[i].e2;
				if(dis[t] > dis[p] + a[i].time)
				{
					dis[t] = dis[p] + a[i].time;
					if(!vis[t])
					{
						vis[t] = true;
						q.push(t);
					}
				}
			}
		}
	}
}
int main()
{
	char s1[100];
	char s2[100];
	int i,j,k;
	int cas = 1;
	while(scanf("%d %d",&n,&m),n||m)
	{
		for(i = 1;i <= m; i++)
		{
			scanf("%d %s %s",&a[i].time,s1,s2);
			a[i].s1 = a[i].s2 = a[i].e1 = a[i].e2 = 0;
			for(j = 0,k = n-1; j < n; j++,k--)
			{
				if(s1[j] == '+')
					a[i].s1 += (1<<k);//+的位置都是1 
				if(s1[j] != '-')
					a[i].s2 += (1<<k);//-的位置都是0  
			}
			for(j = 0,k = n-1; j < n; j++, k--)
			{
				if(s2[j] == '+')
					a[i].e1 += (1<<k);
				if(s2[j] != '-')
					a[i].e2 += (1<<k);
			}
			//printf("%d %d %d %d\n",a[i].s1,a[i].s2,a[i].e1,a[i].e2);
		}
		SPFA();
      	printf("Product %d\n",cas++);  
		if(dis[0] == 999999999) 
  			printf("Bugs cannot be fixed.\n");  
      	else 
  			printf("Fastest sequence takes %d seconds.\n",dis[0]);  
       printf("\n");  
	}
	return 0;
}


 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值