【SCOI 2011】 糖果

【题目链接】

           点击打开链接

【算法】

        当x = 1时,连边(a,b,0)和(b,a,0)

        当x = 2时,连边(a,b,1)

        当x = 3时,连边(b,a,0)

        当x = 4时,连边(b,a,1)

        当x = 5时,连边(a,b,0)

        建立超级源点(Super Source),将这个点与所有点连一条权值为1的边,注意加边时要倒着加,否则会时间超限

【代码】

          

#include<bits/stdc++.h>
using namespace std;
#define MAXN 100010

struct Edge
{
        int to;
        long long w;
        int nxt;
} e[MAXN<<2];

int x,a,b,i,n,k,tot;
long long dis[MAXN];
int head[MAXN];

template <typename T> inline void read(T &x)  
{  
    int f = 1; x = 0;  
    char c = getchar();  
    for (; !isdigit(c); c = getchar()) { if (c == '-') f = -f; }  
    for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';  
    x *= f;  
}  
template <typename T> inline void write(T x)  
{  
    if (x < 0)  
    {  
        putchar('-');  
        x = -x;  
    }  
    if (x > 9) write(x/10);  
    putchar(x%10+'0');  
}  
template <typename T> inline void writeln(T x)  
{  
    write(x);  
    puts("");  
}  
inline void add(int u,int v,long long w)
{
        tot++;
        e[tot] = (Edge){v,w,head[u]};
        head[u] = tot;
}
inline long long spfa()
{
        int i,cur,v;
        long long w,ans = 0;
        queue<int> q;
        static bool inq[MAXN];
        static int cnt[MAXN];
        q.push(0);
        inq[0] = true;
        cnt[0] = 1;
        while (!q.empty())
        {
                cur = q.front();
                q.pop();
                inq[cur] = false;
                for (i = head[cur]; i; i = e[i].nxt)
                {
                        v = e[i].to;
                        w = e[i].w;
                        if (dis[cur] + w > dis[v])
                        {
                                dis[v] = dis[cur] + w;
                                if (!inq[v])
                                {
                                        inq[v] = true;
                                        q.push(v);
                                        cnt[v]++;
                                        if (cnt[v] > n) return -1;
                                }
                        }
                }
        }        
        for (i = 1; i <= n; i++) ans += dis[i];
        return ans;
}

int main() 
{
        
        read(n); read(k);
        for (i = n; i >= 1; i--) add(0,i,1);
        for (i = 1; i <= k; i++)
        {
                read(x); read(a); read(b);
                if (x == 1)
                {
                        add(a,b,0);
                        add(b,a,0);
                }
                if (x == 2) 
                {
                        add(a,b,1);
                        if (a == b) 
                        {
                                writeln(-1);
                                return 0;        
                        } 
                }
                if (x == 3) add(b,a,0);
                if (x == 4) 
                {
                        add(b,a,1); 
                        if (a == b)
                        {
                                writeln(-1);
                                return 0;
                        }
                }
                if (x == 5) add(a,b,0);    
        }
        writeln(spfa());
            
        return 0;
    
}

 


posted @ 2018-06-15 22:36  evenbao  阅读(160)  评论(0编辑  收藏  举报