标签:算法 can 权限 mat 基本 clu 一个人 com else
最近tjm一直在刷bzoj啊...刷题量爆涨看了好激激
蓝鹅自己不知道多久没刷bzoj了
题数一直卡在39好生气...
开始百度->Bzoj ***(算法||数据结构)->Bzoj->找题
tmd怎么那么多权限题(大雾
终于找到一道不是权限题的题了...

给tjm送去一个人头~
看到这种题大概会想到拓扑吧 想 b>a c>b c>a酱紫的
但是看看他又明确的规定说b-a>=1||0...=>差分约束!
然后就分类咯,,,(虽然已经分好了

x=1 即b-a=0||a-b=0
x=2即b>a 转换一下就成了 b-a≥1
x=3即a≥b 转换一下就成了 a-b≥0
x=4即a>b 转换成a-b≥1
x=5即a≤b 转换成 b-a≥0
然后差分基本做法 建边-->跑最短路 至于为什么这种操作看这位大佬的博客吧
我不会告诉你我写了40min的代码调了1h+...(伤手瞎眼掉智商...
最后邻接表打错了也是...(太弱了.jpg
代码:
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
#define maxn 100010
#define ll long long
#define rep(i,l,r,step) for(int i=l;i<=r;i+=step)
bool vis2[maxn];
int dis[maxn],vis1[maxn],q[maxn],edge;
int n,k;
ll ans;
struct zs{
int to,next,dis;
}e[2*maxn];
int head[2*maxn];
//邻接表
void add(int u,int v,int value){
e[++edge].to=v;e[edge].next=head[u];head[u]=edge;e[edge].dis=value;
}
//最短路
bool spfa(){
int hd=0,tail=1;
q[0]=0;vis1[0]=vis2[0]=1;
while(hd!=tail){
int now=q[hd++];if(hd==maxn) hd=0;
for(int i=head[now];i;i=e[i].next){
int v=e[i].to;
if(dis[now]+e[i].dis>dis[v]){
if(++vis1[v]>=n) return 0;
dis[v]=dis[now]+e[i].dis;
if(!vis2[v]){
vis2[v]=1;q[tail++]=v;
if(tail==maxn) tail=0;
}
}
}
vis2[now]=0;
}
return 1;
}
int main(){
scanf("%d%d",&n,&k);
while(k--){
int x,a,b;
scanf("%d%d%d",&x,&a,&b);
if(x==1){
add(a,b,0);add(b,a,0);continue;
}
if(x==2){
if(a==b){printf("-1");return 0;}else add(a,b,1);
continue;
}
if(x==3){
add(b,a,0);continue;
}
if(x==4){
if(a==b){printf("-1");return 0;}else add(b,a,1);continue;
}
if(x==5){
add(a,b,0);continue;
}
}
for(int i=n;i;i--) add(0,i,1);
if(!spfa()){
printf("-1");return 0;
}
rep(i,1,n,1) ans+=dis[i];
printf("%lld\n",ans);
return 0;
}
记录下这美妙的时刻
标签:算法 can 权限 mat 基本 clu 一个人 com else
原文地址:http://www.cnblogs.com/Jrzn/p/7141739.html