bzoj2330

。。。。。。。。。。

。。只想讲一句话,写前向星的同学注意

加(0,i) 边时,一定从n倒叙,,有一组数据卡。。。。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;

struct my{
       int v;
       int next;
       int w;
};

const int maxn=200000+10;
const int nil=0x7f7f7f7f;
queue<int>Q;
int adj[maxn],fa,n,m,d[maxn],inq[maxn],cnt[maxn];
my bian[maxn*5];
bool falg;

void myinsert(int u,int v,int w){
     bian[++fa].v=v;
     bian[fa].next=adj[u];
     adj[u]=fa;
     bian[fa].w=w;
}

bool spfa(int s){
     for (int i=1;i<=n;i++) d[i]=nil;
     d[0]=0;
     ++cnt[0];
     Q.push(0);
     inq[0]=true;
     while(!Q.empty()){
        int u=Q.front();Q.pop();
        inq[u]=false;
        for (int i=adj[u];i;i=bian[i].next){
            int v=bian[i].v;
            if(d[u]<nil&&d[v]>d[u]+bian[i].w){
                d[v]=d[u]+bian[i].w;
                if(!inq[v]){
                    Q.push(v);
                    inq[v]=true;
                    if(++cnt[v]>n) return false;
                }
            }
        }
     }
     return true;
}

int main(){
   // memset(adj,-1,sizeof(adj));
    //memset(bian,-1,sizeof(bian));
    int op, a, b;
    scanf("%d%d", &n, &m);
    //跑最长路的时候我喜欢直接把边权加成负的
    for (int i=n;i>0;i--) myinsert(0,i,-1);
    for (int i=1;i<=m;i++){
        scanf("%d%d%d",&op,&a,&b);
        if(op==1) myinsert(a,b,0),myinsert(b,a,0);
        if(op==2){
            myinsert(a,b,-1);
            if(a==b) falg=1;
        }
        if(op==3) myinsert(b,a,0);
        if(op==4) {
            myinsert(b,a,-1);
            if(a==b) falg=1;
        }
        if(op==5) myinsert(a,b,0);
    }
    //for (int i=10;i<=n+10;i++)
      //  myinsert(0,i,0);
    if(falg) {printf("-1");return 0;}
    if(!spfa(0)) {printf("-1");return 0;}
    long long ans=0;
    for (int i=1;i<=n;i++) ans+=d[i];
    printf("%lld ",-ans);
return 0;
}

 

posted @ 2018-07-30 11:06  lmjer  阅读(122)  评论(0编辑  收藏  举报