Codeforces Round #287 (Div. 2) 507 E. Breaking Good

写的感觉比以前进步许多,就是遍历邻接表的时候感觉是不是要用堆优化一下,第一次交超时了,郁闷了一阵,突然发现忘了把本地测试的#define删掉了,又试了一次就AC了,这题其实就是个BFS,多维护了一个需要修的路的条数,算法上没什么难度
#include<iostream>
#include<string>
#include<cstring>
#include<iomanip>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cmath>
#include<set>
#include<ctime>
#include<cctype>
#include<memory>
#include<cstdlib>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<climits>
#define INF 0x7fffffff
#define db puts("debug");
#define FOR(s,n) for(int i=(s);i<(n);i++)
#define FOR2(s,n) for(int j=(s);j<(n);j++)
typedef long long i64;
#define MX 100005
using namespace std;
struct edge{
    edge(int f,int t,bool s){
        from=f;
        to=t;
        stg=s;
        printed=0;
    }
    int from,to;
    bool printed,stg;
};
vector<edge> G[MX];
int dis[MX];
int prev[MX];
int mcost[MX];
int n,m;
queue<int> nods;
void update(int now){
    int sz=G[now].size();
    vector<edge> &ve=G[now];
    FOR(0,sz){
        edge &e=ve[i];
        if(dis[e.from]+1<dis[e.to]||(dis[e.from]+1==dis[e.to]&&mcost[e.from]+!e.stg<mcost[e.to])){
            prev[e.to]=e.from;
            mcost[e.to]=mcost[e.from]+!e.stg;
            dis[e.to]=dis[e.from]+1;
            nods.push(e.to);
        }
    }
}
int main(){
#ifdef LOCAL
    freopen("in.txt","r",stdin);
   // freopen("out.txt","w",stdout);
#endif // LOCAL
    cin>>n>>m;
    int x,y,s;
    int r1=0;
    FOR(0,m){
        scanf("%d%d%d",&x,&y,&s);
        G[x].push_back(edge(x,y,s));
        G[y].push_back(edge(y,x,s));
        if(s==1)
            r1++;
    }
    memset(dis,0x3f,sizeof dis);
    dis[1]=0;
    nods.push(1);
    int now;
    while(!nods.empty()){
        now=nods.front();
        nods.pop();
        update(now);
    }
    cout<<r1-dis[n]+2*mcost[n]<<endl;
    int t=n,f;
    while(t!=1){
        f=prev[t];
        vector<edge> &ve=G[min(f,t)];
        FOR(0,ve.size()){
            if(ve[i].to==max(f,t)){
                if(ve[i].stg==1){
                    ve[i].printed=1;
                    break;
                }
                printf("%d %d %d\n",ve[i].from,ve[i].to,!ve[i].stg);
                ve[i].printed=1;
                break;
            }
        }
        t=prev[t];
    }
    FOR(1,n+1){
        vector<edge> &ve=G[i];
        FOR2(0,ve.size()){
            edge &e=ve[j];
            if(e.from>e.to)
                continue;
            if(!e.printed&&e.stg==1)
                printf("%d %d %d\n",e.from,e.to,0);
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值