[bzoj3955] [WF2013]Surely You Congest

  首先最短路长度不同的人肯定不会冲突。

  对于最短路长度相同的人,跑个最大流就行了。。当然只有一个人就不用跑了

  看起来会T得很惨。。但dinic在单位网络里是O(m*n^0.5)的...

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<queue>
  6 using namespace std;
  7 const int maxn=25233,inf=1002333333;
  8 struct zs2{
  9     int too,pre,dis;
 10 }e1[100233];int tot1,last1[maxn];
 11 struct zs1{int dis,id;};
 12 priority_queue<zs1>q;
 13 bool u[maxn];
 14 int dis1[maxn];
 15 struct zs{
 16     int too,pre;bool flow;
 17 }e[533333];int tot,last[maxn];
 18 int dl[maxn];
 19 short dis[maxn];
 20 int pos[1023];
 21 int i,j,k,n,m,ans,s,t,tt,c;
 22  
 23 int ra;char rx;
 24 inline int read(){
 25     rx=getchar(),ra=0;
 26     while(rx<'0'||rx>'9')rx=getchar();
 27     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
 28 }
 29  
 30 bool operator <(zs1 a,zs1 b){return a.dis>b.dis;}
 31 inline void spfa(){
 32     int i,now;
 33     memset(dis1,60,(n+1)<<2),dis1[1]=0,q.push((zs1){0,1});
 34     while(!q.empty()){
 35         while(!q.empty()&&u[q.top().id])q.pop();
 36         if(q.empty())return;
 37         now=q.top().id,q.pop(),
 38         u[now]=1;
 39         for(i=last1[now];i;i=e1[i].pre)if(dis1[e1[i].too]>dis1[now]+e1[i].dis)
 40             dis1[e1[i].too]=dis1[now]+e1[i].dis,q.push((zs1){dis1[e1[i].too],e1[i].too});
 41     }
 42 }
 43 inline void insert1(int a,int b,int c){
 44     e1[++tot1].too=b,e1[tot1].dis=c,e1[tot1].pre=last1[a],last1[a]=tot1,
 45     e1[++tot1].too=a,e1[tot1].dis=c,e1[tot1].pre=last1[b],last1[b]=tot1;
 46 }
 47 bool bfs(){
 48     memset(dis,0,(n+1)<<1);
 49     int l=0,r=1,i,now;dl[1]=s,dis[s]=1;
 50     while(l<r&&!dis[t])
 51         for(i=last[now=dl[++l]];i;i=e[i].pre)if(e[i].flow&&!dis[e[i].too])
 52             dis[e[i].too]=dis[now]+1,dl[++r]=e[i].too;
 53 //  for(i=1;i<=n;i++)printf("0->%d  %d\n",i,dis[i]);
 54     return dis[t];
 55 }
 56 int dfs(int x,int mx){
 57     if(x==t)return mx;
 58     int used=0,i;bool w;
 59     for(i=last[x];i;i=e[i].pre)if(e[i].flow&&dis[e[i].too]==dis[x]+1){
 60         w=dfs(e[i].too,1);if(w){
 61             e[i].flow=0,e[i^1].flow=1,used++;
 62             if(used==mx)return mx;
 63         }
 64     }
 65     dis[x]=0;return used;
 66 }
 67 inline void insert(int a,int b,int c){//printf("  %d-->%d  %d\n",a,b,c);
 68     e[++tot].too=b,e[tot].flow=c,e[tot].pre=last[a],last[a]=tot;
 69     e[++tot].too=a,e[tot].flow=0,e[tot].pre=last[b],last[b]=tot;
 70 }
 71 inline int check(int L,int R){//printf("check:  %d--%d\n",L,R);
 72     register int i;int flow=0,j;
 73     for(i=2;i<=tt;i+=2)e[i].flow=1,e[i^1].flow=0;
 74     for(j=1;i<=tot;i+=2,j++)
 75         e[i].flow=j>=L&&j<=R,e[i^1].flow=0;
 76     while(bfs())flow+=dfs(s,inf);
 77 //  printf("flow:  %d\n",flow);
 78     return flow;
 79 }
 80 bool cmp(int a,int b){return dis1[a]<dis1[b];}
 81 int main(){
 82     n=read(),m=read(),c=read();
 83     for(i=1;i<=m;i++)j=read(),k=read(),insert1(j,k,read());
 84     for(i=1;i<=c;i++)pos[i]=read();
 85     spfa();
 86 //  for(i=1;i<=n;i++)printf("1-->%d %d\n",i,dis1[i]);
 87     s=0,t=1,tot=1;
 88     for(i=1;i<=n;i++)for(j=last1[i];j;j=e1[j].pre)
 89         if(dis1[e1[j].too]==dis1[i]+e1[j].dis)insert(e1[j].too,i,1);tt=tot;
 90     sort(pos+1,pos+1+c,cmp);
 91      
 92     for(i=1;i<=c;i++)insert(s,pos[i],0);
 93     int pre;
 94     for(i=1;i<=c&&pos[i]==1;i++,ans++);
 95     for(pre=i;i<=c;i++)if(dis1[pos[i]]!=dis1[pos[i+1]]||i==c){
 96         if(pre==i)ans++;else ans+=check(pre,i);
 97         pre=i+1;
 98     }
 99     printf("%d\n",ans);
100     return 0;
101 }
View Code

dinic好优越啊...

posted @ 2016-06-18 22:30  czllgzmzl  阅读(219)  评论(0编辑  收藏  举报