Light Oj 1316 - A Wedding Party

题目描述:戳这里

题解:

这题一看就可以用状压来解决,复杂度可行。
但是代码改了好久。。。
看来我还是太菜了。。。
代码如下:

#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
const int maxn=20,maxm=177250;
int n,m,tot,ans;
int lnk[maxn],son[maxn*maxn],nxt[maxn*maxn],w[maxn*maxn],f[maxn][maxm],c[maxn];
int inv[maxn];
void clr(){
    tot=0; ans=1<<30;
    memset(lnk,0,sizeof(lnk));
    memset(nxt,0,sizeof(nxt));
    memset(son,0,sizeof(son));
    memset(f,63,sizeof(f));
    memset(w,0,sizeof(w));
}
void add(int x,int y,int z){
    son[++tot]=y,w[tot]=z,nxt[tot]=lnk[x],lnk[x]=tot;
}
bool make_(int x){
    memset(c,0,sizeof(c));
    for (int i=0;i<n;i++) c[i]=x%3,x/=3;
    bool check=0;
    for (int i=0;i<n;i++) if (!c[i]) {check=1; break;}
    return (!check);
}
int make_back(int x){
    int ret=0;
    for (int i=0;i<n;i++) ret+=inv[i]*c[i];
    return f[x][ret];
}
int main(){
    inv[0]=1;
    for (int i=1;i<=12;i++) inv[i]=inv[i-1]*3;
    while (~scanf("%d %d",&n,&m)) {
        clr();
        for (int i=1;i<=m;i++) {
            int x,y,z; scanf("%d %d %d",&x,&y,&z);
            add(x,y,z); add(y,x,z);
        }
        for (int i=0;i<n;i++) f[i+1][inv[i]]=0;
        for (int j=1;j<inv[n];j++)
        for (int i=1;i<=n;i++) {
            bool check=make_(j);
            if (!c[i-1]) continue;
            if (f[i][j]==0) continue;
            c[i-1]--;
            for (int k=lnk[i];k;k=nxt[k])
            if (c[son[k]-1]) f[i][j]=min(f[i][j],make_back(son[k])+w[k]);
            if (check) ans=min(ans,f[i][j]);
        }
        if (ans>1000000000) printf("-1\n"); else printf("%d\n",ans);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值