uva 658 这不是bug,而是特性 二进制转化,(隐式图搜索,最短路,spfa)

主要的难点是把状态转化为二进制表示,下面是二进制的一些用法:

①判定某些位置是否为1,如判定2、4位置为1,则转化为判断x|0101是否等于x。

②判定某些位置是否为0,如判定2、4位置为0,则转化为判断x&1010是否等于x。

③将某些位置转化为1,如2、4位置转化为1,则令x=x|0101。

④将某些位置转化为0,如2、4位置转化为0,则令x=x&1010。

bef[2][i]和aft[2][i]里存的是每个补丁第一个字符串和第二个字符串的信息

for(int j = 0; j < n; j++)
            {
                if(str1[j] == '+')
                    bef[1][i] += (1<<j);
                if(str1[j] != '-')
                    bef[0][i] += (1<<j);
                if(str2[j] == '+')
                    aft[1][i] += (1<<j);
                if(str2[j] != '-')
                    aft[0][i] += (1<<j);
            }

这段代码要理解透彻,注意,用==来判断“+”,而用!=来判断“-”。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <vector>
#define INF 0x3f3f3f3f
using namespace std;

int n, m;
int bef[2][105];
int aft[2][105];
int d[1<<21+1];
int vis[1<<21+1];
int cost[100*100+5];
queue<int> que;

void spfa()
{
	while(!que.empty())	que.pop();
	int ans = (1<<n)-1;
	que.push(ans);
	for(int i = 0; i < ans; i++)
	{
		vis[i] = 0;
		d[i] = INF;
	}
	vis[ans] = 1;
	d[ans] = 0;
	while(!que.empty())
	{
		int front = que.front();
		que.pop();
		vis[front] = 0;
		for(int i = 0; i < m; i++)
		{
			if((front|bef[1][i])==front && (front&bef[0][i])==front)
			{
				int temp;
				temp = front|aft[1][i];
				temp = temp&aft[0][i];
				if(d[front]+cost[i] < d[temp])
				{
					d[temp] = d[front]+cost[i];
					if(!vis[temp])
					{
						que.push(temp);
						vis[temp] = 1;
					}
				}
					
			}
		}
	}
	if(d[0] == INF)	printf("Bugs cannot be fixed.\n");
	else	printf("Fastest sequence takes %d seconds.\n",d[0]);

}
		
int main()
{
	//freopen("ztest.txt","r",stdin);
	//freopen("zans.txt","w",stdout);
	int t = 1;
	while(scanf("%d%d", &n, &m) && (n || m))
	{
		memset(bef, 0, sizeof(bef));
		memset(aft, 0, sizeof(aft));
		if(t != 1)	printf("\n");
		printf("Product %d\n", t++);
		for(int i = 0; i < m; i++)
		{
			scanf("%d", &cost[i]);
			string str1, str2;
			cin >> str1 >> str2;
		//	cout << str1 << endl;
		//	cout << str2 << endl;
			for(int j = 0; j < n; j++)
			{
				if(str1[j] == '+')
					bef[1][i] += (1<<j);
				if(str1[j] != '-')
					bef[0][i] += (1<<j);
				if(str2[j] == '+')
					aft[1][i] += (1<<j);
				if(str2[j] != '-')
					aft[0][i] += (1<<j);
			}
		}
		spfa();
	}
	printf("\n");
	return 0;
}
			
			
			
			
			

猜你喜欢

转载自blog.csdn.net/WukongAKK/article/details/81120657