Codeforces: 877E. Danil and a Part-time Job

0

Problem Link : http://codeforces.com/contest/877/problem/E

Solution Idea:

    Run a dfs on the given for getting the Euler tour order or inorder traversal order. Then the tree is converted to a liner 1D array. Now we can apply range query and update on this array.

    Now use a range update query data structure. Here I have used segment tree. Now initialize the tree with the initial value and now our job is to just toggle a subtree of the given tree and perform query operation. Use a propagation for the update and answer the query.



#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define pii              pair <int,int>
#define pll              pair <long long,long long>
#define sc               scanf
#define pf               printf
#define Pi               2*acos(0.0)
#define ms(a,b)          memset(a, b, sizeof(a))
#define pb(a)            push_back(a)
#define MP               make_pair
#define db               double
#define ll               long long
#define EPS              10E-10
#define ff               first
#define ss               second
#define sqr(x)           (x)*(x)
#define D(x)             cerr<<#x " = "<<(x)<<endl
#define VI               vector <int>
#define DBG              pf("Hi\n")
#define MOD              1000000007
#define CIN              ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define SZ(a)            (int)a.size()
#define sf(a)            scanf("%d",&a)
#define sfl(a)           scanf("%lld",&a)
#define sff(a,b)         scanf("%d %d",&a,&b)
#define sffl(a,b)        scanf("%lld %lld",&a,&b)
#define sfff(a,b,c)      scanf("%d %d %d",&a,&b,&c)
#define sfffl(a,b,c)     scanf("%lld %lld %lld",&a,&b,&c)
#define stlloop(v)       for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define loop(i,n)        for(int i=0;i<n;i++)
#define loop1(i,n)       for(int i=1;i<=n;i++)
#define REP(i,a,b)       for(int i=a;i<b;i++)
#define RREP(i,a,b)      for(int i=a;i>=b;i--)
#define TEST_CASE(t)     for(int z=1;z<=t;z++)
#define PRINT_CASE       printf("Case %d: ",z)
#define LINE_PRINT_CASE  printf("Case %d:\n",z)
#define CASE_PRINT       cout<<"Case "<<z<<": "
#define all(a)           a.begin(),a.end()
#define intlim           2147483648
#define infinity         (1<<28)
#define ull              unsigned long long
#define gcd(a, b)        __gcd(a, b)
#define lcm(a, b)        ((a)*((b)/gcd(a,b)))

using namespace std;

//using namespace __gnu_pbds;
//typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;


/*----------------------Graph Moves----------------*/
//const int fx[]={+1,-1,+0,+0};
//const int fy[]={+0,+0,+1,-1};
//const int fx[]={+0,+0,+1,-1,-1,+1,-1,+1};   // Kings Move
//const int fy[]={-1,+1,+0,+0,+1,+1,-1,-1};  // Kings Move
//const int fx[]={-2, -2, -1, -1,  1,  1,  2,  2};  // Knights Move
//const int fy[]={-1,  1, -2,  2, -2,  2, -1,  1}; // Knights Move
/*------------------------------------------------*/

/*-----------------------Bitmask------------------*/
//int Set(int N,int pos){return N=N | (1<<pos);}
//int reset(int N,int pos){return N= N & ~(1<<pos);}
//bool check(int N,int pos){return (bool)(N & (1<<pos));}
/*------------------------------------------------*/

#define mx 200005
#define segment_tree int l=n*2,r=l+1,mid=(b+e)/2
pii info[mx];
vector<int>g[mx];
int cnt=0;
int maps[mx],ara[mx];

void dfs(int u, int par)
{
    info[u].ff=++cnt;
    maps[cnt]=u;
    for(int i=0;i<SZ(g[u]);i++)
    {
        int v=g[u][i];
        if(v==par) continue;
        dfs(v,u);
    }
    info[u].ss=cnt;
}

struct data
{
    int val, prop;
};

data tree[3*mx];

void push_down(int n, int b, int e)
{
    if(tree[n].prop%2)
    {
        segment_tree;
        tree[l].val=(mid-b+1)-tree[l].val;
        tree[l].prop++;
        tree[r].val=(e-mid)-tree[r].val;
        tree[r].prop++;
        tree[n].prop=0;
    }
}

void init(int n, int b, int e)
{
    if(b==e)
    {
        tree[n].val=ara[maps[b]];
        tree[n].prop=0;
        return;
    }
    segment_tree;
    init(l,b,mid);
    init(r,mid+1,e);
    tree[n].val=tree[l].val+tree[r].val;
}

void update(int n, int b, int e, int i, int j)
{
    if(b>j || e<i) return;
    if(b>=i && e<=j)
    {
        tree[n].val=(e-b+1)-tree[n].val;
        tree[n].prop++;
        return;
    }
    push_down(n,b,e);
    segment_tree;
    update(l,b,mid,i,j);
    update(r,mid+1,e,i,j);
    tree[n].val=tree[l].val+tree[r].val;
}

int query(int n, int b, int e, int i, int j)
{
    if(b>j || e<i) return 0;
    if(b>=i && e<=j) return tree[n].val;
    push_down(n,b,e);
    segment_tree;
    int p=query(l,b,mid,i,j);
    int q=query(r,mid+1,e,i,j);
    return p+q;
}

char str[10];

int main()
{

//    freopen("in.txt","r",stdin);
//	  freopen("out.txt","w",stdout);

    int n;
    sf(n);
    for(int i=2;i<=n;i++)
    {
        int a;
        sf(a);
        g[a].pb(i);
    }

    for(int i=1;i<=n;i++) sf(ara[i]);
    dfs(1,1);
    init(1,1,n);
    int q;
    sf(q);
    while(q--)
    {
        int a;
        scanf(" %s %d",str,&a);
        if(str[0]=='g')
        {
            int x=query(1,1,n,info[a].ff,info[a].ss);
            printf("%d\n",x);
        }
        else
        {
            update(1,1,n,info[a].ff,info[a].ss);
        }
    }



    return 0;
}

Codeforce gym: 101484 F. No Link, Cut Tree!

0

Problem Link : http://codeforces.com/gym/101484/problem/F

Solution Idea:

    My solution idea for this problem is at first make the given tree a full binary tree. A full binary tree (sometimes proper binary tree or 2-tree) is a tree in which every node other than the leaves has two children. On the other hand A complete binary tree is a binary tree in which every level, except possibly the last, is completely filled, and all nodes are as far left as possible. So we can convert a complete binary tree to a full binary tree by adding some dummy node whose cost is 0 so that they don’t contribute anything in the solution as well as they will help us to form our solution.

    Now classify the nodes according to their level and make their cumulative sum or insert them in segment tree or in a binary indexed tree. We need this data structure for every level. Now map the nodes by the inorder traversal of the tree and position of the level array like 1,2,3….

    Now here comes an important observation in a full binary tree at any level, if I want to delete a subtree starting at node u the will need to delete 1 node from level[u], 2 node from level[u]+1, 4 node from level[u]+2…2^i node form level[u]+i.

    Now form the data structure (here I have used Binary Indexed Tree(BIT)) just query the contribution of the deleted node subtract them form the total contribution of that level and take the maximum. We need to do this from level[u] to last level and we need to consider the whole level from level 1 to level[u]-1.


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define pii              pair <int,int>
#define pll              pair <long long,long long>
#define sc               scanf
#define pf               printf
#define Pi               2*acos(0.0)
#define ms(a,b)          memset(a, b, sizeof(a))
#define pb(a)            push_back(a)
#define MP               make_pair
#define db               double
#define ll               long long
#define EPS              10E-10
#define ff               first
#define ss               second
#define sqr(x)           (x)*(x)
#define D(x)             cerr<<#x " = "<<(x)<<endl
#define VI               vector <int>
#define DBG              pf("Hi\n")
#define MOD              1000000007
#define CIN              ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define SZ(a)            (int)a.size()
#define sf(a)            scanf("%d",&a)
#define sfl(a)           scanf("%lld",&a)
#define sff(a,b)         scanf("%d %d",&a,&b)
#define sffl(a,b)        scanf("%lld %lld",&a,&b)
#define sfff(a,b,c)      scanf("%d %d %d",&a,&b,&c)
#define sfffl(a,b,c)     scanf("%lld %lld %lld",&a,&b,&c)
#define stlloop(v)       for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define loop(i,n)        for(int i=0;i<n;i++)
#define loop1(i,n)       for(int i=1;i<=n;i++)
#define REP(i,a,b)       for(int i=a;i<b;i++)
#define RREP(i,a,b)      for(int i=a;i>=b;i--)
#define TEST_CASE(t)     for(int z=1;z<=t;z++)
#define PRINT_CASE       printf("Case %d: ",z)
#define LINE_PRINT_CASE  printf("Case %d:\n",z)
#define CASE_PRINT       cout<<"Case "<<z<<": "
#define all(a)           a.begin(),a.end()
#define intlim           2147483648
#define infinity         (1<<28)
#define ull              unsigned long long
#define gcd(a, b)        __gcd(a, b)
#define lcm(a, b)        ((a)*((b)/gcd(a,b)))

using namespace std;

//using namespace __gnu_pbds;
//typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;


/*----------------------Graph Moves----------------*/
//const int fx[]={+1,-1,+0,+0};
//const int fy[]={+0,+0,+1,-1};
//const int fx[]={+0,+0,+1,-1,-1,+1,-1,+1};   // Kings Move
//const int fy[]={-1,+1,+0,+0,+1,+1,-1,-1};  // Kings Move
//const int fx[]={-2, -2, -1, -1,  1,  1,  2,  2};  // Knights Move
//const int fy[]={-1,  1, -2,  2, -2,  2, -1,  1}; // Knights Move
/*------------------------------------------------*/

/*-----------------------Bitmask------------------*/
//int Set(int N,int pos){return N=N | (1<<pos);}
//int reset(int N,int pos){return N= N & ~(1<<pos);}
//bool check(int N,int pos){return (bool)(N & (1<<pos));}
/*------------------------------------------------*/

#define mx 200005

vector<int>g[mx];

vector<int>level_g[20];

int map1[mx],levell[mx];
int map2_level[mx],cost[mx],max_depth,disc;
int tree[20][mx];
int n,m;


void dfs1(int u, int level)
{
    max_depth=max(max_depth,level);
    for(int i=0;i<SZ(g[u]);i++)
    {
        int v=g[u][i];
        dfs1(v,level+1);
    }
}

void dfs(int u, int par, int level)
{
    levell[u]=level;
//    max_depth=max(max_depth,level);
    map1[u]=++disc;
    level_g[level].pb(u);

    if(levell[u]!=max_depth)
    {
        if(SZ(g[u])==0)
            g[u].pb(++n);
        if(SZ(g[u])==1)
            g[u].pb(++n);
    }

    for(int i=0;i<SZ(g[u]);i++)
    {
        int v=g[u][i];
        if(v==par) continue;
        dfs(v,u,level+1);
    }
}



void update(int id, int idx, int val)
{
    for(int i=idx;i<mx;i+=(i&-i))
        tree[id][i]+=val;
}

int query(int id, int idx)
{
    int ret=0;
    for(int i=idx;i>0;i-=(i&-i))
        ret+=tree[id][i];
    return ret;
}

int main()
{
//    freopen("in.txt","r",stdin);
//	  freopen("out.txt","w",stdout);


    sff(n,m);
    sf(cost[1]);

    for(int i=1;i<n;i++)
    {
        int a,b,c;
        sfff(a,b,c);
        g[b].pb(a);
        cost[a]=c;
    }
    dfs1(1,1);
//    int xx=n;
//    for(int i=1;i<=xx;i++)
//    {
//        if(SZ(g[i])==1)
//            g[i].pb(++n);
//    }

    dfs(1,1,1);

    for(int i=1;i<=max_depth;i++)
    {
        int num=0;
        for(int j=0;j<SZ(level_g[i]);j++)
        {
            int v=level_g[i][j];
            map2_level[map1[v]]=++num;
            update(i,num,cost[v]);
        }
    }

    while(m--)
    {
        int u;
        sf(u);
        int ans=0;
        for(int i=1;i<levell[u];i++)
            ans=max(ans,query(i,mx-1));
        int last=levell[u],pp=0,cur=map1[u];
        for(int i=levell[u];i<=max_depth;i++)
        {
            int total=query(i,mx-1);
            int sub=query(i,map2_level[cur]+(1<<pp)-1);
            int sub1=query(i,map2_level[cur]-1);
            total-=(sub-sub1);
            ans=max(ans,total);
            pp++;
            cur++;
        }

        printf("%d\n",ans);

    }



    return 0;
}

DFS Sample Code

0

#include <bits/stdc++.h>

using namespace std;

vector<int>v[100];
bool visited[100];

int node,edge;

void DFS(int n)
{
    visited[n]=true;
    cout<<n<<" ";
    int temp;
    for(int i=0; i<v[n].size(); i++)
    {
        temp=v[n][i];
        if(!visited[temp])
            DFS(temp);
    }
}


int main()
{
    cin>>node>>edge;
    for(int i=0; i<edge; i++)
    {
        int x,y;
        cin>>x>>y;
        v[x].push_back(y);
        v[y].push_back(x);
    }

    int src,dst;
    cin>>src>>dst;
    memset(visited,0,sizeof visited);
    cout<<"DFS traverse order is = ";
    DFS(src);
    cout<<endl;
    if(visited[dst])
        cout<<dst<<" is reachable from "<<src<<endl;
    else
        cout<<dst<<" is not reachable from "<<src<<endl;
    return 0;
}


USACO: The Castle

0

Problem Link : http://train.usaco.org/usacoprob2?a=qBACVBxoOsW&S=castle


/*
PROG: castle
LANG: C++
*/

#include <bits/stdc++.h>

#define pii             pair <int,int>
#define sc              scanf
#define pf              printf
#define Pi              2*acos(0.0)
#define ms(a,b)         memset(a, b, sizeof(a))
#define pb(a)           push_back(a)
#define MP              make_pair
#define db              double
#define ll              long long
#define EPS             10E-10
#define ff              first
#define ss              second
#define sqr(x)          (x)*(x)
#define D(x)            cout<<#x " = "<<(x)<<endl
#define VI              vector <int>
#define DBG             pf("Hi\n")
#define MOD             100007
#define MAX             10000
#define CIN             ios_base::sync_with_stdio(0); cin.tie(0)
#define SZ(a)           (int)a.size()
#define sf(a)           scanf("%d",&a)
#define sfl(a)          scanf("%lld",&a)
#define sff(a,b)        scanf("%d %d",&a,&b)
#define sffl(a,b)       scanf("%lld %lld",&a,&b)
#define sfff(a,b,c)     scanf("%d %d %d",&a,&b,&c)
#define sfffl(a,b,c)    scanf("%lld %lld %lld",&a,&b,&c)
#define loop(i,n)       for(int i=0;i<n;i++)
#define REP(i,a,b)      for(int i=a;i<=b;i++)
#define TEST_CASE(t)    for(int z=1;z<=t;z++)
#define PRINT_CASE      printf("Case %d: ",z)
#define all(a)          a.begin(),a.end()
#define intlim          2147483648
#define inf             1000000
#define ull             unsigned long long

using namespace std;


/*----------------------Graph Moves----------------*/
//const int fx[]={+1,-1,+0,+0};
//const int fy[]={+0,+0,+1,-1};
//const int fx[]={+0,+0,+1,-1,-1,+1,-1,+1};   // Kings Move
//const int fy[]={-1,+1,+0,+0,+1,+1,-1,-1};  // Kings Move
//const int fx[]={-2, -2, -1, -1,  1,  1,  2,  2};  // Knights Move
//const int fy[]={-1,  1, -2,  2, -2,  2, -1,  1}; // Knights Move
/*------------------------------------------------*/

/*-----------------------Bitmask------------------*/
//int Set(int N,int pos){return N=N | (1<<pos);}
//int reset(int N,int pos){return N= N & ~(1<<pos);}
bool check(int N,int pos)
{
    return (bool)(N & (1<<pos));
}
/*------------------------------------------------*/

int graph[52][52];
int dp[2505];
int visited[52][52];

int r,c,s,extend=0;

int dfs(int i, int j, int x)
{
//    if(visited[i][j]) return 0;
    visited[i][j]=x;
    int d=0;
    if(!check(graph[i][j],0) && !visited[i][j-1]) d+=1+dfs(i,j-1,x);
    if(!check(graph[i][j],2) && !visited[i][j+1]) d+=1+dfs(i,j+1,x);
    if(!check(graph[i][j],1) && !visited[i-1][j]) d+=1+dfs(i-1,j,x);
    if(!check(graph[i][j],3) && !visited[i+1][j]) d+=1+dfs(i+1,j,x);
    return d;
}

int n,m;

void func(int i, int j,int x)
{
    int t=visited[i][j];
    int d=0;
    if(check(graph[i][j],0) && t!=visited[i][j-1] && j-1>=1)
    {
        d=dp[t]+dp[visited[i][j-1]];
        if(d>extend)
        {
            extend=d;
            r=i,c=j;
            s=0;
        }
        else if(d==extend)
        {
            if(j<c)
            {
                r=i,c=j;
                s=0;
            }
            else if(j==c)
            {
                if(i>r)
                {
                    r=i,j=c;
                    s=0;
                }
            }
        }
    }

    if(check(graph[i][j],2) && t!=visited[i][j+1] && j+1<=m)
    {
        d=dp[t]+dp[visited[i][j+1]];
        if(d>extend)
        {
            extend=d;
            r=i,c=j;
            s=2;
        }
        else if(d==extend)
        {
            if(j<c)
            {
                r=i,c=j;
                s=2;
            }
            else if(j==c)
            {
                if(i>r)
                {
                    r=i,j=c;
                    s=2;
                }
                else if(i==r)
                {
                    if(s!=1)
                    {
                        r=i,j=c;
                        s=2;
                    }
                }
            }
        }
    }

    // if(check(graph[i][j],2) && !visited[i][j+1]) d+=1+dfs(i,j+1,x);
    //if(check(graph[i][j],1) && !visited[i-1][j]) d+=1+dfs(i-1,j,x);
    if(check(graph[i][j],1) && t!=visited[i-1][j] && i-1>=1)
    {
        d=dp[t]+dp[visited[i-1][j]];
        if(d>extend)
        {
            extend=d;
            r=i,c=j;
            s=1;
        }
        else if(d==extend)
        {
            if(j<c)
            {
                r=i,c=j;
                s=1;
            }
            else if(j==c)
            {
                if(i>r)
                {
                    r=i,j=c;
                    s=1;
                }
                else if(i==r)
                {
                    r=i,j=c;
                    s=1;
                }
            }
        }
    }
    //if(check(graph[i][j],3) && !visited[i+1][j]) d+=1+dfs(i+1,j,x);

    if(check(graph[i][j],3) && t!=visited[i+1][j] && i+1<=n)
    {
        d=dp[t]+dp[visited[i+1][j]];
        if(d>extend)
        {
            extend=d;
            r=i,c=j;
            s=3;
        }
        else if(d==extend)
        {
            if(j<c)
            {
                r=i,c=j;
                s=3;
            }
            else if(j==c)
            {
                if(i>r)
                {
                    r=i,j=c;
                    s=3;
                }
            }
        }
    }
}

int main()
{
    freopen("castle.in","r",stdin);
    freopen("castle.out","w",stdout);
    cin>>n>>m;
    swap(n,m);
    REP(i,1,n) REP(j,1,m) cin>>graph[i][j];

    int k=0;
    int ans=-1;
    REP(i,1,n) REP(j,1,m)
    {
        if(!visited[i][j])
        {
            k++;
            dp[k]=dfs(i,j,k)+1;
            ans=max(ans,dp[k]);
        }
    }

    cout<<k<<endl<<ans<<endl;
    REP(i,1,n) REP(j,1,m)
    {
        func(i,j,visited[i][j]);
//        cout<<i<<" "<<j<<" "<<extend<<" "<<s<<endl;
    }
    cout<<extend<<endl;
    cout<<r<<" "<<c;
    if(s==2)pf(" E\n");
    else
        pf(" N\n");
    return 0;
}

USACO: Superprime Rib

0

Problem Link : http://train.usaco.org/usacoprob2?a=tffkkLavmsp&S=sprime


/*
PROG: sprime
LANG: C++
*/

#include <bits/stdc++.h>

#define pii             pair <int,int>
#define sc              scanf
#define pf              printf
#define Pi              2*acos(0.0)
#define ms(a,b)         memset(a, b, sizeof(a))
#define pb(a)           push_back(a)
#define MP              make_pair
#define db              double
#define ll              long long
#define EPS             10E-10
#define ff              first
#define ss              second
#define sqr(x)          (x)*(x)
#define D(x)            cout<<#x " = "<<(x)<<endl
#define VI              vector <int>
#define DBG             pf("Hi\n")
#define MOD             100007
#define MAX             10000
#define CIN             ios_base::sync_with_stdio(0); cin.tie(0)
#define SZ(a)           (int)a.size()
#define sf(a)           scanf("%d",&a)
#define sfl(a)          scanf("%lld",&a)
#define sff(a,b)        scanf("%d %d",&a,&b)
#define sffl(a,b)       scanf("%lld %lld",&a,&b)
#define sfff(a,b,c)     scanf("%d %d %d",&a,&b,&c)
#define sfffl(a,b,c)    scanf("%lld %lld %lld",&a,&b,&c)
#define loop(i,n)       for(int i=0;i<n;i++)
#define REP(i,a,b)      for(int i=a;i<b;i++)
#define TEST_CASE(t)    for(int z=1;z<=t;z++)
#define PRINT_CASE      printf("Case %d: ",z)
#define all(a)          a.begin(),a.end()
#define intlim          2147483648
#define inf             1000000
#define ull             unsigned long long

using namespace std;


/*----------------------Graph Moves----------------*/
//const int fx[]={+1,-1,+0,+0};
//const int fy[]={+0,+0,+1,-1};
//const int fx[]={+0,+0,+1,-1,-1,+1,-1,+1};   // Kings Move
//const int fy[]={-1,+1,+0,+0,+1,+1,-1,-1};  // Kings Move
//const int fx[]={-2, -2, -1, -1,  1,  1,  2,  2};  // Knights Move
//const int fy[]={-1,  1, -2,  2, -2,  2, -1,  1}; // Knights Move
/*------------------------------------------------*/

/*-----------------------Bitmask------------------*/
//int Set(int N,int pos){return N=N | (1<<pos);}
//int reset(int N,int pos){return N= N & ~(1<<pos);}
//bool check(int N,int pos){return (bool)(N & (1<<pos));}
/*------------------------------------------------*/

vector<ll>v;
int n;

bool isprime(ll n)
{
    if(n==2) return 1;
    if(!(n & 1)) return 0;

    for(int i=3; i*i<=n; i+=2)
        if(n%i==0) return 0;
    return 1;
}

void dfs(ll u,int m)
{
    if(!isprime(u)) return;
    if(m==n)
    {
        v.pb(u);
        return;
    }
    for(int i=1; i<=9; i+=2)
    {
        int x=u*10+i;
        dfs(x,m+1);
    }
}

int main()
{
    freopen("sprime.in","r",stdin);
    freopen("sprime.out","w",stdout);
    cin>>n;
    for(int i=2; i<=9; i++)
        dfs(i,1);
    sort(all(v));
    loop(i,SZ(v)) cout<<v[i]<<endl;
    return 0;
}

Light OJ : 1168 – Wishing Snake

0

Problem Link : http://www.lightoj.com/volume_showproblem.php?problem=1168

Algorithm :

1. Make a graph from input data and Determine the SCC of the graph.
2. Make a new Graph from SCC. Consider Each SCC as a node of this graph.
3. If any Node of SCC_graph have more than 1 out degree and It is not possible to traverse all node from the SCC which contain’s the node 0 of the input graph then Print “NO”.
4. Otherwise Print “YES”;


/*
         +-+ +-+ +-+
         |R| |.| |S|
         +-+ +-+ +-+
 */

#include <bits/stdc++.h>

#define pii             pair <int,int>
#define sc              scanf
#define pf              printf
#define Pi              2*acos(0.0)
#define ms(a,b)         memset(a, b, sizeof(a))
#define pb(a)           push_back(a)
#define MP              make_pair
#define db              double
#define ll              long long
#define EPS             10E-10
#define ff              first
#define ss              second
#define sqr(x)          (x)*(x)
#define D(x)            cout<<#x " = "<<(x)<<endl
#define VI              vector <int>
#define DBG             pf("Hi\n")
#define MOD             100007
#define MAX             1005
#define CIN             ios_base::sync_with_stdio(0); cin.tie(0)
#define SZ(a)           (int)a.size()
#define sf(a)           scanf("%d",&a)
#define sff(a,b)        scanf("%d%d",&a,&b)
#define sfff(a,b,c)     scanf("%d%d%d",&a,&b,&c)
#define loop(i,n)       for(int i=0;i<n;i++)
#define REP(i,a,b)      for(int i=a;i<b;i++)
#define TEST_CASE(t)    for(int z=1;z<=t;z++)
#define PRINT_CASE      printf("Case %d: ",z)
#define all(a)          a.begin(),a.end()
#define intlim          2147483648
#define inf             1000000
#define ull             unsigned long long

using namespace std;


const int fx[]={+1,-1,+0,+0};
const int fy[]={+0,+0,+1,-1};

vector<int>graph[MAX],rev_graph[MAX],scc_graph[MAX];
int visited[MAX];
int node[MAX],scc_num[MAX],node_num,scc;
stack<int>st;
bool test,scc_vis[MAX];

void allclear()
{
    loop(i,node_num+2)
    {
        visited[i]=0;
        graph[i].clear();
        rev_graph[i].clear();
        scc_num[i]=0;
    }
    loop(i,scc+2)
    {
        scc_graph[i].clear();
        scc_vis[i]=0;
    }
    node_num=0;
    scc=0;
}

void dfs1(int u)
{
    visited[u]++;
    loop(i,SZ(graph[u]))
    {
        int v=graph[u][i];
        if(visited[v]==0)
            dfs1(v);
    }
    st.push(u);
}

void dfs2(int u)
{
    visited[u]++;
    scc_num[u]=scc;
    loop(i,SZ(rev_graph[u]))
    {
        int v=rev_graph[u][i];
        if(visited[v]!=2)
            dfs2(v);
    }
}

void dfs3(int u)
{
    scc_vis[u]=1;
    if(SZ(scc_graph[u])>1)
        {test=0;return;}
    loop(i,SZ(scc_graph[u]))
    dfs3(scc_graph[u][i]);
}

int main()
{
    ///freopen("in.txt","r",stdin);
    ///freopen("out.txt","w",stdout);

    int t;
    sf(t);
    TEST_CASE(t)
    {
        ms(node,-1);
        int n,m,u,v;
        node_num=0;
        node[0]=node_num;
        sf(n);
        loop(i,n)
        {
            sf(m);
            loop(j,m)
            {
                sff(u,v);
                if(node[u]==-1) node[u]=++node_num;
                if(node[v]==-1) node[v]=++node_num;
                graph[node[u]].pb(node[v]);
                rev_graph[node[v]].pb(node[u]);
            }
        }

        loop(i,node_num)
        {
            if(visited[i]==0)
                dfs1(i);
        }

        scc=0;
        while(!st.empty())
        {
            u=st.top();
            st.pop();
            if(visited[u]!=2)
            {
                scc++;
                dfs2(u);
            }
        }

        loop(i,node_num)
        {
            loop(j,SZ(graph[i]))
            {
                u=graph[i][j];
                if(scc_num[i]!=scc_num[u])
                    scc_graph[scc_num[i]].pb(scc_num[u]);
            }
        }

        test=1;
        dfs3(scc_num[0]);
        if(test)
        {
            REP(i,1,scc+1)
            {
                if(!scc_vis[i])
                    test=0;
            }
        }
        PRINT_CASE;
        if(test)
            pf("YES\n");
        else
            pf("NO\n");
        allclear();

    }
    return 0;
}


Light OJ : 1417 – Forwarding Emails

0

Problem Link : http://www.lightoj.com/volume_showproblem.php?problem=1417


/*
         +-+ +-+ +-+
         |R| |.| |S|
         +-+ +-+ +-+
 */
 
#include <bits/stdc++.h>
 
#define pii             pair <int,int>
#define sc              scanf
#define pf              printf
#define Pi              2*acos(0.0)
#define ms(a,b)         memset(a, b, sizeof(a))
#define pb(a)           push_back(a)
#define MP              make_pair
#define db              double
#define ll              long long
#define EPS             10E-10
#define ff              first
#define ss              second
#define sqr(x)          (x)*(x)
#define D(x)            cout<<#x " = "<<(x)<<endl
#define VI              vector <int>
#define DBG             pf("Hi\n")
#define MOD             100007
#define MAX             50005
#define CIN             ios_base::sync_with_stdio(0); cin.tie(0)
#define SZ(a)           (int)a.size()
#define sf(a)           scanf("%d",&a)
#define sff(a,b)        scanf("%d%d",&a,&b)
#define sfff(a,b,c)     scanf("%d%d%d",&a,&b,&c)
#define loop(i,n)       for(int i=0;i<n;i++)
#define REP(i,a,b)      for(int i=a;i<b;i++)
#define TEST_CASE(t)    for(int z=1;z<=t;z++)
#define PRINT_CASE      printf("Case %d: ",z)
#define all(a)          a.begin(),a.end()
#define intlim          2147483648
#define inf             1000000
#define ull             unsigned long long
 
using namespace std;
 
int n,dfsnum,dis[MAX];
vector<int> graph[MAX],rev_graph[MAX];
bool mp[MAX],mp1[MAX],mp2[MAX];
 
void allclear()
{
    loop(i,n+2)
    {
        graph[i].clear();
        rev_graph[i].clear();
        dis[i]=0;
        mp[i]=mp1[i]=mp2[i]=0;
    }
    dfsnum=0;
}
 
void dfs1(int u)
{
    mp[u]=1;
    dfsnum++;
    loop(i,SZ(graph[u]))
    {
        int v=graph[u][i];
        if(!mp[v])
            dfs1(v);
    }
    dis[u]=++dfsnum;
}
 
void dfs2(int u)
{
    mp1[u]=1;
    loop(i,SZ(rev_graph[u]))
    {
        int v=rev_graph[u][i];
        if(!mp1[v])
            dfs2(v);
    }
}
 
void dfs3(int u)
{
    mp2[u]=1;
    dfsnum++;
    loop(i,SZ(graph[u]))
    {
        int v=graph[u][i];
        if(!mp2[v])
            dfs3(v);
    }
}
 
void dfs4(int u)
{
    mp2[u]=0;
    loop(i,SZ(graph[u]))
    {
        int v=graph[u][i];
        if(mp2[v])
            dfs4(v);
    }
}
 
int main()
{
    ///freopen("in.txt","r",stdin);
    ///freopen("out.txt","w",stdout);
 
    int t;
    sf(t);
    TEST_CASE(t)
    {
        sf(n);
        allclear();
        int a,b;
        loop(i,n)
        {
            sff(a,b);
            graph[a].pb(b);
            rev_graph[b].pb(a);
        }
        REP(i,1,n+1)
        {
            if(!mp[i])
                dfs1(i);
        }
 
        vector<pii>top_sort;
        REP(i,1,n+1)
        {
            top_sort.pb(MP(dis[i],i));
        }
 
 
        sort(top_sort.rbegin(),top_sort.rend());
        vector<int>scc;
 
        loop(i,SZ(top_sort))
        {
            int u=top_sort[i].ss;
            if(!mp1[u])
            {
                scc.pb(u);
                dfs2(u);
            }
        }
 
        top_sort.clear();
        loop(i,SZ(scc))
        {
            int u=scc[i];
            if(!mp2[u])
            {
                dfsnum=0;
                dfs3(u);
                top_sort.pb(MP(dfsnum,u));
                dfs4(u); // this DFS is clearing only visited node.
            }
        }
 
        sort(top_sort.rbegin(),top_sort.rend());
        PRINT_CASE;
        if(SZ(top_sort)==1)
            pf("%d\n",top_sort[0].ss);
        else
        {
            loop(i,SZ(top_sort)-1)
            {
                if(top_sort[i].ff!=top_sort[i+1].ff) // This is for determine the smallest one.
                {
                    pf("%d\n",top_sort[i].ss);
                    break;
                }
            }
        }
    }
    return 0;
}

Light OJ 1108 – Instant View of Big Bang

0

Problem Link : http://www.lightoj.com/volume_showproblem.php?problem=1108

Algorithm:

1. Make a graph by reverse the edge direction.
2. Run Bellman Ford in reverse Graph and check if there exist a negative weight cycle. Reversing edge doesn’t affect in cycle because if we reverse the edge direction then cycle remain unchanged.
3. If exist a negative cycle then run a DFS on the reverse graph for finding the nodes which are reachable from negative cycle and store them in a vector and after sorting the vector print them.
4. If there is no negative cycle then print impossible.


/*
         +-+ +-+ +-+
         |R| |.| |S|
         +-+ +-+ +-+
 */

#include <bits/stdc++.h>

#define pii             pair <int,int>
#define sc              scanf
#define pf              printf
#define Pi              2*acos(0.0)
#define ms(a,b)         memset(a, b, sizeof(a))
#define pb(a)           push_back(a)
#define MP              make_pair
#define db              double
#define ll              long long
#define EPS             10E-10
#define ff              first
#define ss              second
#define sqr(x)          (x)*(x)
#define D(x)            cout<<#x " = "<<(x)<<endl
#define VI              vector <int>
#define DBG             pf("Hi\n")
#define MOD             100007
#define MAX             1005
#define CIN             ios_base::sync_with_stdio(0); cin.tie(0)
#define SZ(a)           (int)a.size()
#define sf(a)           scanf("%d",&a)
#define sff(a,b)        scanf("%d%d",&a,&b)
#define sfff(a,b,c)     scanf("%d%d%d",&a,&b,&c)
#define loop(i,n)       for(int i=0;i<n;i++)
#define REP(i,a,b)      for(int i=a;i<b;i++)
#define TEST_CASE(t)    for(int z=1;z<=t;z++)
#define PRINT_CASE      printf("Case %d: ",z)
#define all(a)          a.begin(),a.end()
#define intlim          2147483648
#define inf             1000000
#define ull             unsigned long long

using namespace std;

struct data
{
    int u,v,w;
    data(int x, int y, int z)
    {
        u=x,v=y,w=z;
    }
};

int n,m,total_edge;
vector<data> graph;
vector<int>ans,reverse_graph[MAX];
map<int,bool>mp;
int d[MAX];
bool visited[MAX];

void dfs(int u)
{
    mp[u]=1;
    ans.pb(u);
    loop(i,SZ(reverse_graph[u]))
    {
        int v=reverse_graph[u][i];
        if(!mp[v])
            dfs(v);
    }
}

bool bellmanford()
{
    for(int i=1;i<n;i++)
    {
        loop(i,m)
        {
            int u=graph[i].u;
            int v=graph[i].v;
            if(d[u]+graph[i].w<d[v])
            {
                d[v]=d[u]+graph[i].w;
            }
        }
    }

    bool negative_cycle=0;

    loop(i,m)
        {
            int u=graph[i].u;
            int v=graph[i].v;
            if(d[u]+graph[i].w<d[v])
            {
                negative_cycle=1;
                d[v]=d[u]+graph[i].w;
                if(!mp[u])
                    dfs(u);
            }
        }
        return negative_cycle;
}

void allclear()
{
    graph.clear();
    ans.clear();
    mp.clear();

    loop(i,n+2)
        {d[i]=inf;reverse_graph[i].clear();}
}

int main()
{
    ///freopen("in.txt","r",stdin);
    ///freopen("out.txt","w",stdout);
    int t;
    sf(t);
    TEST_CASE(t)
    {
        int u,v,w;
        sff(n,m);
        allclear();
        loop(i,m)
        {
            sfff(u,v,w);
            graph.pb(data(v,u,w));//reversing graph
            reverse_graph[v].pb(u);
        }
        
        PRINT_CASE;
        if(bellmanford())
        {
            sort(all(ans));
            pf("%d",ans[0]);
            REP(i,1,SZ(ans))
            pf(" %d",ans[i]);
            pf("\n");
        }
        else
            pf("impossible\n");
    }
    return 0;
}


Light OJ 1034 – Hit the Light Switches

0

Problem Link : http://www.lightoj.com/volume_showproblem.php?problem=1034


/*
         +-+ +-+ +-+
         |R| |.| |S|
         +-+ +-+ +-+
 */

#include <bits/stdc++.h>

#define pii             pair <int,int>
#define sc              scanf
#define pf              printf
#define Pi              2*acos(0.0)
#define ms(a,b)         memset(a, b, sizeof(a))
#define pb(a)           push_back(a)
#define MP              make_pair
#define db              double
#define ll              long long
#define EPS             10E-10
#define ff              first
#define ss              second
#define sqr(x)          (x)*(x)
#define D(x)            cout<<#x " = "<<(x)<<endl
#define VI              vector <int>
#define DBG             pf("Hi\n")
#define MOD             100007
#define MAX             10005
#define CIN             ios_base::sync_with_stdio(0); cin.tie(0)
#define SZ(a)           (int)a.size()
#define sf(a)           scanf("%d",&a)
#define sff(a,b)        scanf("%d%d",&a,&b)
#define sfff(a,b,c)     scanf("%d%d%d",&a,&b,&c)
#define loop(i,n)       for(int i=0;i<n;i++)
#define REP(i,a,b)      for(int i=a;i<b;i++)
#define TEST_CASE(t)    for(int z=1;z<=t;z++)
#define PRINT_CASE      printf("Case %d: ",z)
#define all(a)          a.begin(),a.end()
#define intlim          2147483648
#define inf             1000000
#define ull             unsigned long long

using namespace std;

int n,m;
vector<int>graph[MAX],topsort;
bool visited[MAX],test;

void allclear()
{
    loop(i,n+2)
    {
        graph[i].clear();
        visited[i]=0;
    }
    topsort.clear();
}

void dfs(int u)
{
    visited[u]=1;
    loop(i,SZ(graph[u]))
    {
        int v=graph[u][i];
        if(!visited[v])
            dfs(v);
    }
    if(test)
        topsort.pb(u);
}

int main()
{
    ///freopen("in.txt","r",stdin);
    ///freopen("out.txt","w",stdout);
    int t,a,b;
    sf(t);
    TEST_CASE(t)
    {
        sff(n,m);
        loop(i,m)
        {
            sff(a,b);
            graph[a].pb(b);
        }
        test=1;
        int ans=0;
        REP(i,1,n+1)
        {
            if(!visited[i])
                dfs(i);
        }

        test=0;
        loop(i,n+2) visited[i]=0;
        for(int i=SZ(topsort)-1; i>=0; i--)
        {
            int u=topsort[i];
            if(!visited[u])
            {
                dfs(u);
                ans++;
            }
        }
        PRINT_CASE;
        pf("%d\n",ans);
        allclear();
    }
    return 0;
}


Another solution of this problem using Strongly Connected components(SCC) is here…


/*
         +-+ +-+ +-+
         |R| |.| |S|
         +-+ +-+ +-+
 */

#include <bits/stdc++.h>

#define pii             pair <int,int>
#define sc              scanf
#define pf              printf
#define Pi              2*acos(0.0)
#define ms(a,b)         memset(a, b, sizeof(a))
#define pb(a)           push_back(a)
#define MP              make_pair
#define db              double
#define ll              long long
#define EPS             10E-10
#define ff              first
#define ss              second
#define sqr(x)          (x)*(x)
#define D(x)            cout<<#x " = "<<(x)<<endl
#define VI              vector <int>
#define DBG             pf("Hi\n")
#define MOD             100007
#define MAX             10005
#define CIN             ios_base::sync_with_stdio(0); cin.tie(0)
#define SZ(a)           (int)a.size()
#define sf(a)           scanf("%d",&a)
#define sff(a,b)        scanf("%d%d",&a,&b)
#define sfff(a,b,c)     scanf("%d%d%d",&a,&b,&c)
#define loop(i,n)       for(int i=0;i<n;i++)
#define REP(i,a,b)      for(int i=a;i<b;i++)
#define TEST_CASE(t)    for(int z=1;z<=t;z++)
#define PRINT_CASE      printf("Case %d: ",z)
#define all(a)          a.begin(),a.end()
#define intlim          2147483648
#define inf             1000000
#define ull             unsigned long long

using namespace std;

int n,m;
vector<int>graph[MAX],reverse_graph[MAX],scc;
vector<pii>v;
int indegree[MAX],topsort[MAX],finish;
bool visited[MAX];

void allclear()
{
    loop(i,n+2)
    {
        graph[i].clear();
        reverse_graph[i].clear();
        indegree[i]=0;
        visited[i]=0;
        topsort[i];
    }
    scc.clear();
    v.clear();
    finish=0;
}

void dfs1(int u)
{
    finish++;
    visited[u]=1;
    loop(i,SZ(graph[u]))
    {
        int v=graph[u][i];
        if(!visited[v])
            dfs1(v);
    }
    topsort[u]=++finish;
}

void dfs2(int u)
{
    visited[u]=1;
    loop(i,SZ(reverse_graph[u]))
    {
        int v=reverse_graph[u][i];
        if(!visited[v])
            dfs2(v);
    }
}

void dfs3(int u)
{
    visited[u]=1;
    loop(i,SZ(graph[u]))
    {
        int v=graph[u][i];
        if(!visited[v])
            dfs3(v);
    }
}
int main()
{
    ///freopen("in.txt","r",stdin);
    ///freopen("out.txt","w",stdout);
    int t,a,b;
    sf(t);
    TEST_CASE(t)
    {
        sff(n,m);
        loop(i,m)
        {
            sff(a,b);
            graph[a].pb(b);
            reverse_graph[b].pb(a);
            indegree[b]++;
        }

        int ans=0;
        REP(i,1,n+1)
        {
            if(!visited[i])
                dfs1(i);
        }

        REP(i,1,n+1)
        {
            v.pb(MP(topsort[i],i));
        }
        sort(all(v));
        loop(i,n+2)
        visited[i]=0;

        for(int i=SZ(v)-1; i>=0; i--)
        {
            int u=v[i].ss;
            if(!visited[u])
            {
                scc.pb(u);
                dfs2(u);
            }
        }

        loop(i,n+2)
        visited[i]=0;

        loop(i,SZ(scc))
        {
            if(!visited[scc[i]])
            {
                ans++;
                dfs3(scc[i]);
            }
        }
        PRINT_CASE;
        pf("%d\n",ans);
        allclear();
    }
    return 0;
}


Light OJ 1337 – The Crystal Maze

0

Problem Link : http://www.lightoj.com/volume_showproblem.php?problem=1337


/*
         +-+ +-+ +-+
         |R| |.| |S|
         +-+ +-+ +-+
 */

#include <bits/stdc++.h>

#define pii             pair <int,int>
#define sc              scanf
#define pf              printf
#define Pi              2*acos(0.0)
#define ms(a,b)         memset(a, b, sizeof(a))
#define pb(a)           push_back(a)
#define MP              make_pair
#define db              double
#define ll              long long
#define EPS             10E-10
#define ff              first
#define ss              second
#define sqr(x)          (x)*(x)
#define D(x)            cout<<#x " = "<<(x)<<endl
#define VI              vector <int>
#define DBG             pf("Hi\n")
#define MOD             100007
#define MAX             10000
#define CIN             ios_base::sync_with_stdio(0); cin.tie(0)
#define SZ(a)           (int)a.size()
#define sf(a)           scanf("%d",&a)
#define sff(a,b)        scanf("%d%d",&a,&b)
#define sfff(a,b,c)     scanf("%d%d%d",&a,&b,&c)
#define loop(i,n)       for(int i=0;i<n;i++)
#define REP(i,a,b)      for(int i=a;i<b;i++)
#define TEST_CASE(t)    for(int z=1;z<=t;z++)
#define PRINT_CASE      printf("Case %d:\n",z)
#define all(a)          a.begin(),a.end()
#define intlim          2147483648
#define inf             1000000
#define ull             unsigned long long

using namespace std;


const int fx[]={+1,-1,+0,+0};
const int fy[]={+0,+0,+1,-1};

char graph[502][502];
int dp[502][502];
bool visited[502][502];
bool dpvisited[502][502];
int n,m,cnt;

bool test(int x, int y)
{
    if(visited[x][y] || x<0 || x>=n || y<0 || y>=m || graph[x][y]=='#') return 1;
    return 0;
}

bool dptest(int x, int y)
{
    if(dpvisited[x][y] || x<0 || x>=n || y<0 || y>=m || graph[x][y]=='#') return 1;
    return 0;
}

void dfs1(int x, int y)
{
    if(test(x,y)) return;
    visited[x][y]=1;
    if(graph[x][y]=='C')
        cnt++;
    loop(i,4)
    dfs1(x+fx[i],y+fy[i]);
}

void dfs2(int x, int y)
{
        if(dptest(x,y)) return;
        dpvisited[x][y]=1;
        dp[x][y]=cnt;
        loop(i,4)
        dfs2(x+fx[i],y+fy[i]);
}

void allclear()
{
    loop(i,n) loop(j,m)
    {
        visited[i][j]=dpvisited[i][j]=0;
        dp[i][j]=-1;
    }
}

int main()
{
    ///freopen("in.txt","r",stdin);
    ///freopen("out.txt","w",stdout);
    int t,p,q,k;
    sf(t);
    TEST_CASE(t)
    {
        sfff(n,m,k);
        getchar();
        allclear();
        loop(i,n)
        gets(graph[i]);
        PRINT_CASE;
        while(k--)
        {
            sff(p,q);
            p--;q--;
            if(graph[p][q]=='#')
            {
                pf("0\n");
                continue;
            }
            else if(visited[p][q])
            {
                pf("%d\n",dp[p][q]);
            }
            else
            {
                cnt=0;
                dfs1(p,q);
                dfs2(p,q);
                pf("%d\n",dp[p][q]);
            }
        }
    }
    return 0;
}