2017.3.18 糖果 思考记录

来源:互联网 发布:工程类 网络类 编辑:程序博客网 时间:2024/06/04 19:08

        其实差分约束自己也看过了,看来做题和学算法是两码事(其实就是没系统学过

          借此来看一看差分约束吧


首先要确定你要跑的是最短路还是最大路:

如果题目要求是至少、最小值,就跑最长路,相应的不等号也应该是a-b<=,b向a建;

如果题目要求是最多、最大值,就跑最短路,相应的不等号也应该是a-b>=,a向b建;

证:

若跑的是最短路,则有任一点 b,所有的a到原点的距离 +a 到b的距离<=b到原点的距离

若不等式为a-b>=5;

则可化为b<=a-5;

所以a向b连权值为 -5的边。


另:最好不要另建立原点,不然长链会T飞、


码(这题竟然卡int):

#include<iostream>#include<cstdio>using namespace std;#include<queue>#include<cstring>#define N 400005#define M 1000006queue<int>q;long long ans;int tot,s,zhong[M],xia[N],hou[M],zhi[M],i,dis[N],n,m,sum[N],k,x,a,b; bool vis[N];void jian(int x,int y,int z){zhong[++tot]=y,hou[tot]=xia[x],xia[x]=tot,zhi[tot]=z;}bool spfa(){for(i=1;i<=n;i++)     q.push(i),vis[i]=dis[i]=sum[i]=1;                   //cout<<"pp";while(!q.empty()){   int st=q.front();q.pop();//cout<<st<<" ";vis[st]=0; for(i=xia[st];i!=-1;i=hou[i]){int nd=zhong[i];     if(dis[nd]<dis[st]+zhi[i]) {        dis[nd]=dis[st]+zhi[i];++sum[nd];if(sum[nd]>n)return 0;if(!vis[nd]){vis[nd]=1;q.push(nd); }     }}}return 1;}int main(){memset(xia,-1,sizeof(xia));scanf("%d%d",&n,&k);for(i=1;i<=k;i++){scanf("%d%d%d",&x,&a,&b);if(x==1){jian(a,b,0);jian(b,a,0);}if(x==2){if(a==b){puts("-1");return 0;}jian(a,b,1);}if(x==3){  jian(b,a,0);}if(x==4){if(a==b){puts("-1");return 0;}jian(b,a,1);}if(x==5){jian(a,b,0);}}if(!spfa()){puts("-1");return 0;}for(i=1;i<=n;i++){ans+=(long long)dis[i];}cout<<ans;}

0 0
原创粉丝点击