實際上是挺好的一道題node
正着實在很差作,還要考慮當前點是否能夠傳遞,c++
能夠提早把整個鏈都處理出來,例如第一秒點燈把整條鏈都染上色算法
然而你不知道終止時間ide
枚舉終止時間便可學習
算是時光倒流spa
還有,感謝wwb_apecode
#include<bits/stdc++.h> using namespace std; #define ll long long #define A 111 ll sta[A],light[A],qw[A],fa[A],ff[35][35],f[35][1<<17|1]; ll vis[20]; ll n,ans=0x3f3f3f3f,top,mudi; int main(){ freopen("decoration.in","r",stdin); freopen("decoration.out","w",stdout); scanf("%lld",&n); for(ll i=2;i<=n;i++) scanf("%lld",&fa[i]); for(ll i=1;i<=n;i++){ scanf("%lld",&qw[i]); if(qw[i]==1) mudi|=1<<(i-1); } ll maxn=(1<<n)-1; fa[1]=0; for(ll i=1;i<=32;i++){ for(ll j=1;j<=n;j++){ ll cnt=0,now=j,tot=n-i; while(cnt<=tot&&now!=0){ cnt++; ff[i][j]|=1<<(now-1); // printf("ff[%lld][%lld]=%lld now=%lld\n",i,j,ff[i][j],now); now=fa[now]; } } } f[n+1][0]=1; for(ll i=n;i>=1;i--){ for(ll j=0;j<=maxn;j++){ if(!f[i+1][j]) continue ; for(ll k=1;k<=n;k++){ f[i][j^ff[i][k]]|=f[i+1][j]; // printf("f[%lld][%lld]=%lld i+1=%lld j=%lld\n",i,j^ff[i][k],f[i+1][j],i+1,j); } f[i][j]|=f[i+1][j]; // printf("f[%lld][%lld]=%lld\n",i,j,f[i][j]); // printf("mudi=%lld\n",mudi); if(f[i][mudi]){ printf("%lld\n",n-i+1); return 0; } } } }
考場真是什麼也沒想出來blog
暴力都沒打對,真是沒救了it
還好我如今稍微會了一點io
有一個奇怪的子任務:不存在肯定沒有學會毒瘤算法的同窗。
看上去這個子任務給的性質好像沒什麼用
咱們仍是能夠推一推
貪心取L便可
證實感性理解一下
因而f[x]=min(f[x],L)
最短路形式,能夠用最短路轉移
而後將這個子任務推廣
若是存在沒有學會毒瘤算法的同窗就是至關於給上述轉移加了一個限制條件
例如
現有wwb,whs二人
已知wwb學習毒瘤算法時間在>R,那麼就意味着此次吃飯時whs也不會毒瘤算法
仍然貪心考慮
whs和wwb二人吃飯於L,而後whs在L+1學會毒瘤算法,就知足限制了
因而lim[x]=max(L+1)
先把lim算出來,再轉移f就能夠了
#include<bits/stdc++.h> using namespace std; #define ll long long #define A 1111111 ll n,m,tot; ll vis[A],mn[A],mx[A],head[A],nxt[A],ver[A],dis[A],flag[A],lst[A],lim[A]; struct node{ ll x,y,l,r; node(){} node(const ll &a,const ll &b,const ll &c,const ll &d){x=a,y=b,l=c,r=d;} }u[A]; void add(ll x,ll y,ll minn,ll maxx){ nxt[++tot]=head[x],ver[tot]=y,head[x]=tot,mn[tot]=minn,mx[tot]=maxx; } void pre_spfa(){ deque<ll> q; for(ll i=1;i<=n;i++){ scanf("%lld",&lst[i]); if(lst[i]==-1) lim[i]=1e9+7,vis[i]=1,q.push_back(i); else vis[i]=0; } while(!q.empty()){ ll x=q.front();q.pop_front(); vis[x]=0; for(ll i=head[x];i;i=nxt[i]){ ll y=ver[i],minn=mn[i],maxx=mx[i]; if(lim[x]>maxx){ if(lim[y]<minn+1){ lim[y]=minn+1; if(!vis[y]){ vis[y]=1; q.push_back(y); } } } } } } void spfa(){ deque<ll> q; for(ll i=1;i<=n;i++) vis[i]=0,dis[i]=1e9+7; dis[1]=0;q.push_back(1); while(!q.empty()){ ll x=q.front();q.pop_front(); vis[x]=0; for(ll i=head[x];i;i=nxt[i]){ ll y=ver[i],minn=mn[i],maxx=mx[i],g=max(max(lim[y],minn),dis[x]); // printf("y=%lld minn=%lld maxx=%lld g=%lld\n",y,minn,maxx,g); if(dis[y]>g&&g<=maxx){ dis[y]=g; // printf("dis[%lld]=%lld\n",y,dis[y]); if(!vis[y]){ vis[y]=1; q.push_back(y); } } } } } int main(){ freopen("lunch.in","r",stdin); freopen("lunch.out","w",stdout); scanf("%lld%lld",&n,&m); for(ll i=1;i<=m;i++){ ll x,y,a,b; scanf("%lld%lld%lld%lld",&x,&y,&a,&b); add(x,y,a,b); add(y,x,a,b); u[i]=node(x,y,a,b); } pre_spfa(); spfa(); for(ll i=1;i<=n;i++) if(lst[i]==1&&dis[i]>1e9){ puts("Impossible\n"); return 0; } for(ll i=1;i<=m;i++){ ll x=u[i].x,y=u[i].y; if(lst[x]==-1&&dis[y]<u[i].l){ puts("Impossible\n"); return 0; } if(lst[y]==-1&&dis[x]<u[i].l){ puts("Impossible\n"); return 0; } } // for(ll i=1;i<=n;i++) // printf("lim=%lld dis=%lld\n",lim[i],dis[i]); for(ll i=1;i<=m;i++){ ll x=u[i].x,y=u[i].y; if(lst[x]==-1||lst[y]==-1) printf("%lld\n",u[i].l); else printf("%lld\n",max(dis[x],dis[y])>u[i].r?u[i].l:max(u[i].l,max(dis[x],dis[y]))); } }