[POI 2015] bzoj 4383 Pustynia - 선분 수 최적화 설계도

6752 단어 선분 수BZOJ
매번 보조 점 을 만 든 후 선분 수 최적화 건 도 를 만 들 면 됩 니 다. 특 판 a [i] ≤ 109 a [i] ≤ 10 9 에 주의 하 십시오.
#include
#include
#include
#include
#include
#define gc getchar()
#define LEN 100010
#define LOG 20
#define N (LEN*LOG+400010)
#define M (N*2)
#define INF 1000000000
#define debug(x) cerr<
#define sp <
#define ln <
using namespace std;
inline int inn()
{
    int x,ch;while((ch=gc)<'0'||ch>'9');
    x=ch^'0';while((ch=gc)>='0'&&ch<='9')
        x=(x<<1)+(x<<3)+(ch^'0');return x;
}
struct edges{
    int to,pre;
}e[M];int h[N],a[N],Log[LEN],etop,up[LEN][LOG],isf[N],d[N],t[N];queue<int> q;
inline int add_edge(int u,int v) { return e[++etop].to=v,e[etop].pre=h[u],h[u]=etop,d[v]++; }
inline int Add(int x,int s,int t)
{
    if(s>t) return 0;int k=Log[t-s+1];
    if(s==t) add_edge(x,up[s][0]);
    else add_edge(x,up[s][k]),add_edge(x,up[t-(1<1][k]);
    return 0;
}
inline int toposort(int n,int c=0)
{
    for(int i=1;i<=n;i++) if(!d[i]) q.push(i);
    while(!q.empty())
    {
        int x=q.front();q.pop(),t[++c]=x;
        for(int i=h[x],y;i;i=e[i].pre)
            if(!(--d[y=e[i].to])) q.push(y);
    }
    return 0;
}
int main()
{
    int n=inn(),s=inn(),m=inn(),c=n;
    for(int i=1,x;i<=s;i++) x=inn(),a[x]=inn();
//  for(int i=1;i<=n;i++) debug(i)sp,debug(a[i])ln;
    for(int i=2;i<=n;i++) Log[i]=Log[i>>1]+1;
    for(int i=1;i<=n;i++) add_edge(up[i][0]=++c,i);
    for(int j=1;(1<for(int i=1;i+(1<1<=n;i++)
            up[i][j]=++c,add_edge(up[i][j],up[i][j-1]),
            add_edge(up[i][j],up[i+(1<1))][j-1]);
    while(m--)
    {
        int l=inn(),r=inn(),k=inn(),las=l-1,fz=++c,x;
        while(k--) x=inn(),add_edge(x,fz),Add(fz,las+1,x-1),las=x;
        Add(fz,las+1,r),isf[fz]=1;
    }
    toposort(c);
    for(int i=1;i<=n;i++) if(d[i]) return !printf("NIE
"
); for(int j=c,x;j;j--) if(a[x=t[j]]) { for(int i=h[x],y;i;i=e[i].pre) if(a[x]return !printf("NIE"); } else{ if(x<=n) a[x]=1; for(int i=h[x],y;i;i=e[i].pre) a[x]=max(a[x],a[e[i].to]+isf[e[i].to]); } for(int i=1;i<=n;i++) if(a[i]>INF) return !printf("NIE"); printf("TAK"); for(int i=1;i<=n;i++) printf("%d ",a[i]); return !printf(""); }

좋은 웹페이지 즐겨찾기