HDU3663--Power Stations(Dancing Links)

Problem Description
There are N towns in our country, and some of them are connected by electricity cables. It is known that every town owns a power station. When a town’s power station begins to work, it will provide electric power for this town and the neighboring towns which are connected by cables directly to this town. However, there are some strange bugs in the electric system –One town can only receive electric power from no more than one power station, otherwise the cables will be burned out for overload.

The power stations cannot work all the time. For each station there is an available time range. For example, the power station located on Town 1 may be available from the third day to the fifth day, while the power station on Town 2 may be available from the first day to the forth day. You can choose a sub-range of the available range as the working time for each station. Note that you can only choose one sub-range for each available range, that is, once the station stops working, you cannot restart it again. Of course, it is possible not to use any of them.

Now you are given all the information about the cable connection between the towns, and all the power stations’ available time. You need to find out a schedule that every town will get the electricity supply for next D days, one and only one supplier for one town at any time.
 

Input
There are several test cases. The first line of each test case contains three integers, N, M and D (1 <= N <= 60, 1 <= M <= 150, 1 <= D <= 5), indicating the number of towns is N, the number of cables is M, and you should plan for the next D days. 

Each of the next M lines contains two integers a, b (1 <= a, b <= N), which means that Town a and Town b are connected directly. Then N lines followed, each contains two numbers si and ei, (1 <= si <= ei <= D) indicating that the available time of Town i’s power station is from the si-th day to the ei-th day (inclusive).
 

Output
For each test case, if the plan exists, output N lines. The i-th line should contain two integers ui and vi, indicating that Town i’s power station should work from the ui-th day to vi-day (inclusive). If you didn’t use this power station at all, set ui = vi = 0.

If the plan doesn’t exist, output one line contains “No solution” instead. 

Note that the answer may not be unique. Any correct answers will be OK.

Output a blank line after each case.
 

Sample Input
3 3 5 1 2 2 3 3 1 1 5 1 5 1 5 4 4 5 1 2 2 3 3 4 4 1 1 5 1 5 1 5 1 5
 

Sample Output
1 5 0 0 0 0 No solution
思路:首先要懂Dancing Links。不懂先找knuth的X算法看。。
每個城市D天都要有電供應,可以想到將列分爲n*d。。每個城市選擇開動發電廠的時間必須連續,可將其根據對應區間分爲若干行。也就是枚舉開發電廠的頭尾。。但這樣又有一個問題,如果這樣直接DLX會可能出現某個發電廠選多次。自然聯想到列多出n列,表示選了該發電廠。那麼求一次精確覆蓋後就不會出現發電廠選多次的情況了。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
const int maxnode = 100010;
const int MaxM = 2010;
const int MaxN = 2010;
int first[MaxN],vv[MaxN],nxt[MaxN],fuck[6],from[MaxN],to[MaxN];
bool vis[68][68];
int e;
void init()
{
	fuck[1] = 2;	fuck[2] = 4;	fuck[3] = 7;	fuck[4] = 11;	fuck[5] = 16;
	memset(vis,0,sizeof(vis));
	e = 0;
	memset(first,-1,sizeof(first));
}
void addedge(int u,int v)
{
	vv[e] = v;	nxt[e] = first[u];	first[u] = e++;
	//vv[e] = u;	nxt[e] = first[v];	first[v] = e++;
}

struct Worktime
{
	int from,to;
}worktime[MaxN];
struct DLX
{
    int n,m,size;
    int U[maxnode],D[maxnode],R[maxnode],L[maxnode],Row[maxnode],Col[maxnode];
    int H[MaxN], S[MaxM];
    int ansd, ans[MaxN];
    void init(int _n,int _m)
    {
        n = _n;
        m = _m;
        for(int i = 0;i <= m;i++)
        {
            S[i] = 0;
            U[i] = D[i] = i;
            L[i] = i-1;
            R[i] = i+1;
        }
        R[m] = 0; L[0] = m;
        size = m;
        for(int i = 1;i <= n;i++)
            H[i] = -1;
    }
    void Link(int r,int c)
    {
        ++S[Col[++size]=c];
        Row[size] = r;
        D[size] = D[c];
        U[D[c]] = size;
        U[size] = c;
        D[c] = size;
        if(H[r] < 0)H[r] = L[size] = R[size] = size;
        else
        {
            R[size] = R[H[r]];
            L[R[H[r]]] = size;
            L[size] = H[r];
            R[H[r]] = size;
        }
    }
    void remove(int c)
    {
        L[R[c]] = L[c]; R[L[c]] = R[c];
        for(int i = D[c];i != c;i = D[i])
            for(int j = R[i];j != i;j = R[j])
            {
                U[D[j]] = U[j];
                D[U[j]] = D[j];
                --S[Col[j]];
            }
    }
    void resume(int c)
    {
        for(int i = U[c];i != c;i = U[i])
            for(int j = L[i];j != i;j = L[j])
                ++S[Col[U[D[j]]=D[U[j]]=j]];
        L[R[c]] = R[L[c]] = c;
    }
    bool Dance(int d)
    {
        if(R[0] == 0)
        {
            ansd = d;
            return true;
        }
        int c = R[0];
        for(int i = R[0];i != 0;i = R[i])
            if(S[i] < S[c])
                c = i;
        remove(c);
        for(int i = D[c];i != c;i = D[i])
        {
            ans[d] = Row[i];
            for(int j = R[i]; j != i;j = R[j])remove(Col[j]);
            if(Dance(d+1))return true;
            for(int j = L[i]; j != i;j = L[j])resume(Col[j]);
        }
        resume(c);
        return false;
    }
};

DLX g;
int main()
{
	//freopen("in.txt","r",stdin);
	int n,m,d;
	while(scanf("%d%d%d",&n,&m,&d)==3)
	{
		init();
		for(int i = 1;i <= m;i++)
		{
			int u,v;
			scanf("%d%d",&u,&v);
			if(!vis[u][v] && u!=v)
			{
				addedge(v,u);
				addedge(u,v);
			}
			vis[u][v] = vis[v][u] = 1;
		}
		for(int i = 1;i <= n;i++)
			if(!vis[i][i])	addedge(i,i);
		int hang = 0,lie = n*d+n;
		for(int i = 1;i <= n;i++)
		{
			int u,v;
			scanf("%d%d",&u,&v);
			worktime[i].from = u,worktime[i].to = v;
			hang += fuck[v-u+1];
		}
		g.init(hang,lie);
		int pos = 0;
		for(int i = 1;i <= n;i++)
		{
			int u = worktime[i].from,v = worktime[i].to;
			++pos;	g.Link(pos,n*d+i);
			from[pos] = 0;	to[pos] = 0;
			for(int ss = u;ss <= v;ss++)
			{
				for(int tt = ss;tt <= v;tt++)
				{
					++pos;
					from[pos] = ss,to[pos] = tt;
					for(int j = first[i];j != -1;j = nxt[j])
					{
						int vvv = vv[j];
						for(int k = ss;k <= tt;k++)
						{
							g.Link(pos,(k-1)*n+vvv);
						}
					}
					g.Link(pos,n*d+i);
				}
			}
		}
		if(!g.Dance(0))	printf("No solution\n");
		else 
		{
			sort(g.ans,g.ans+g.ansd);
			for(int i = 0;i < g.ansd;i++)
			{
				int a = g.ans[i];
				cout << from[a] << " " << to[a] << endl;
			}
		}
		cout << endl;
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章