cf 507E. Breaking Good

因为要求是在保证最短路的情况下花费是最小的,所以(先保证最短路设为S吧)

那么花费就是最短路上的新建边条数A+剩余拆掉边的条数B,而且总的原有好的边是一定的,所以,只要使得A尽量小,那么B就大,所以要拆掉的边也会少啦。

所以SPFA以最短路为基础,维护出一个A最小就好。(路径什么的,,from[...])

  1 #include<bits/stdc++.h>
  2 #define INF 0x7fffffff
  3 #define inf 0x3f3f3f3f
  4 #define LL long long
  5 #define N 100005
  6 using namespace std;
  7 inline LL ra()
  8 {
  9     LL x=0,f=1; char ch=getchar();
 10     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
 11     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
 12     return x*f;
 13 }
 14 struct node{
 15     int from,to,next,z;
 16 }e[N<<2];
 17 int sum[N<<1],dis[N<<1],head[N<<1],cnt;
 18 int q[N<<4],tot1,n,m,from[N<<1];
 19 bool vis[N<<1],inq[N<<1];
 20 void insert(int x, int y, int z)
 21 {
 22     e[cnt].to=y;
 23     e[cnt].from=x;
 24     e[cnt].next=head[x];
 25     e[cnt].z=z;
 26     head[x]=cnt++;
 27 }
 28 void SPFA()
 29 {
 30     for (int i=1; i<=n; i++) sum[i]=dis[i]=inf;
 31     sum[1]=dis[1]=0; q[0]=1; int l=0,r=1; from[1]=-1;
 32     while (l<=r)
 33     {
 34         int x=q[l++];
 35          for (int i=head[x];i!=-1;i=e[i].next)
 36         {
 37             if (dis[e[i].to]==dis[x]+1 && e[i].z==0)
 38             {
 39                 if (sum[e[i].to]>sum[x]+1)
 40                 {
 41                     sum[e[i].to]=sum[x]+1;
 42                     from[e[i].to]=i;
 43                     if (!inq[e[i].to])
 44                     {
 45                         q[r++]=e[i].to;
 46                         inq[e[i].to]=1;
 47                     }
 48                 }
 49             }
 50             if (dis[e[i].to]==dis[x]+1 && e[i].z)
 51             {
 52                 if (sum[e[i].to]>sum[x])
 53                 {
 54                     sum[e[i].to]=sum[x];
 55                     from[e[i].to]=i;
 56                     if (!inq[e[i].to])
 57                     {
 58                         q[r++]=e[i].to;
 59                         inq[e[i].to]=1;
 60                     }
 61                 }
 62             }
 63             if (dis[e[i].to]>dis[x]+1)
 64             {
 65                 dis[e[i].to]=dis[x]+1;
 66                 from[e[i].to]=i;
 67                 if (e[i].z==0) sum[e[i].to]=sum[x]+1;
 68                     else sum[e[i].to]=sum[x];
 69                 if (!inq[e[i].to])
 70                 {
 71                     inq[e[i].to]=1;
 72                     q[r++]=e[i].to;
 73                 }
 74             }
 75         }
 76         inq[x]=0;
 77     }
 78 //    cout<<dis[n];while (1);
 79 }
 80 void print()
 81 {
 82     cout<<sum[n]+(tot1-(dis[n]-sum[n]))<<endl;
 83     int i=from[n];
 84     while (i!=-1)
 85     {
 86         if (e[i].z==0)
 87             printf("%d %d 1\n",e[i].from,e[i].to);
 88         else vis[i]=1;
 89         i=from[e[i].from];
 90     }
 91     for (int i=1; i<=cnt; i++)
 92     {
 93         if (e[i].z==1 && vis[i]==0 && vis[i^1]==0)
 94         {
 95             vis[i]=1;
 96             printf("%d %d 0\n",e[i].from,e[i].to);
 97         }
 98     }
 99 }
100 int main()
101 {
102     n=ra(); m=ra();
103     memset(head,-1,sizeof(head));
104     for (int i=1; i<=m; i++)
105     {
106         int x=ra(),y=ra(),z=ra();
107         if (z==1) tot1++;
108         insert(x,y,z); insert(y,x,z);
109     }
110     SPFA();
111     print();
112     return 0;
113 }

 

posted @ 2017-02-10 10:11  ws_ccd  阅读(161)  评论(0编辑  收藏  举报