拓扑+状压DP求调
查看原帖
拓扑+状压DP求调
556238
NicolasSU楼主2023/7/7 09:22
#include<bits/stdc++.h>
// 拓扑 + 状压DP 
using namespace std;
 
int const N = 2e3, M = 4e5;
long long n;
long long sx, sy, ex, ey, c[N];
long long k[N][N], cnt[N];
vector< long long > way[N];
long long t[M][23];
bool check[N];
char d[N];
long long POW(long long x, long long s)
{
    long long sum = 1;
    while(s--) sum *= x;
    return sum;
}
long long Turn(string x)
{
    long long s = 0, sum = 0;
    for(int i = 0; i < x.size(); i++) 
        if(x[i] == '1') sum += POW(2,s++);
    return sum;
}
void inti()
{
    bool flag[N];
    for(int i = 1; i <= n; i++)
    {
        memset(flag, false, sizeof(flag));
        cin >> sy >> sx >> ey >> ex >>c[i];
        for(int j = sx; j <= ex; j++) k[ey][j] = i;
        for(int j = sx; j <= ex; j++) if(k[sy][j] && !flag[k[sy][j]]) cnt[i]++, way[k[sy][j]].push_back(i), flag[k[sy][j]] = true;
    }
}
void f(long long T, long long x, int col)
{   
//
    d[x] = '1';
    check[x] = true;
    for(int i = 0; i < way[x].size(); i++) cnt[way[x][i]]--;
    string s;
    for(int i = 1; i <= n; i++) 
        if(d[i] == '1') s += '1';
        else s += '0';
    long long h = Turn(s);
//
    if(t[h][col] < T)
    {
        d[x] = '0';
        check[x] = false;
        for(int i = 0; i < way[x].size(); i++) cnt[way[x][i]]++;
        return;
    }
//
    t[h][col] = T;
    for(int i = 1; i <= n; i++)
    {
        if(check[i]) continue;
        if(!cnt[i])
        {
            if(c[i] != col) f(T + 1, i, c[i]);
            else f(T, i, col);
        }
    }
//
    d[x] = '0';
    check[x] = false;
    for(int i = 0; i < way[x].size(); i++) cnt[way[x][i]]++;
}
int main()
{
    memset(t, 0x3f, sizeof(t));
    scanf("%lld", &n);
    inti();
    for(int i = 1; i <= n; i++)  
        if(!cnt[i]) f(1, i, c[i]);
    long long Ans = 0x3f, g = POW(2,n) - 1;
    for(int i = 1; i <= 20; i++) 
        Ans = min (Ans, t[g][i]);
    printf("%lld", Ans); 
}
2023/7/7 09:22
加载中...