zoukankan      html  css  js  c++  java
  • [USACO15JAN]Grass Cownoisseur

    (tarjan)缩点+(DAG)上最长路。
    求一个以(1)为起点的最长路和一个以(1)为终点的最长路,然后找那个逆行边就行了。
    然后这个我(RE)了好久,原因是(vector)(size()) (return)的是一个(unsigned int)值,如果直接(size()-1),会让显示的值变成(Max Unsigned Int),然后就RE了。。。问问问

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <bitset>
    #include <cmath>
    #include <queue>
    #include <ctime>
    #include <set>
    #include <map>
    #define fo(i,j,k) for(int i=(j);i<=(k);i++)
    #define fd(i,j,k) for(int i=j;i>=k;i--)
    #define go(i,k) for(int i=head[k],v=e[i].to;i;i=e[i].nxt,v=e[i].to)
    using namespace std;
    typedef long long ll;
    typedef double db;
    const int inf=0x3f3f3f3f;
    inline int rd() {
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
        return x*f;
    }
    const int M=100005,N=100005;
    int n,m,dfn[N],low[N],tim,ecnt,head[N],stk[N],top,siz[N],col[N],cnt,dis1[N],dis2[N];
    bool vis[N];
    struct Edge{int to,nxt;}e[M];
    vector<int>G[N],F[N];
    void add(int bg,int ed) {e[++ecnt]=(Edge){ed,head[bg]};head[bg]=ecnt;}
    void tarjan(int x) {
        low[x]=dfn[x]=++tim;vis[x]=1;stk[++top]=x;
        go(i,x) {
            if(!dfn[v]) {
                tarjan(v);
                low[x]=min(low[x],low[v]);
            }
            else if (vis[v]) low[x]=min(low[x],dfn[v]);
        }
        if(dfn[x]==low[x]) {
            col[x]=++cnt;vis[x]=0;siz[cnt]=1;
            while(stk[top]!=x) {
                col[stk[top]]=cnt;
                siz[cnt]++;
                vis[stk[top]]=0;
                top--;
            }
            top--;
        }
    }
    queue<int>q;
    void spfa1() {
        memset(vis,0,sizeof vis);
        q.push(col[1]);
        dis1[col[1]]=siz[col[1]];
        while(!q.empty()) {
            int u=q.front();q.pop();vis[u]=0;
            for(int i=0;i<G[u].size();i++) {
                int v=G[u][i];
                if(dis1[v]<dis1[u]+siz[v]) {
                    dis1[v]=dis1[u]+siz[v];
                    if(!vis[v]) q.push(v),vis[v]=1;
                }
            }
        }
    }
    void spfa2() {
        memset(vis,0,sizeof vis);
        dis2[col[1]]=siz[col[1]];
        q.push(col[1]);
        while(!q.empty()) {
            int u=q.front();q.pop();vis[u]=0;
            for(int i=0;i<F[u].size();i++) {
                int v=F[u][i];
                if(dis2[v]<dis2[u]+siz[v]) {
                    dis2[v]=dis2[u]+siz[v];
                    if(!vis[v]) q.push(v),vis[v]=1;
                }
            }
        }
    }
    int main() {
    #ifdef HSZ
        freopen(".in","r",stdin);
        freopen(".out","w",stdout);
    #endif
        n=rd(),m=rd();
        int u,v;
        fo(i,1,m) u=rd(),v=rd(),add(u,v);
        fo(i,1,n) if(!dfn[i]) tarjan(i);
        fo(i,1,n) {
            go(j,i) 
                if(col[i]!=col[v]) G[col[i]].push_back(col[v]),F[col[v]].push_back(col[i]);
        }
        spfa1();
        spfa2();
        int ans=siz[col[1]];
        fo(i,1,n) {
            if(!vis[col[i]]&&dis1[col[i]]) {
                vis[col[i]]=1;
                fo(j,0,(int)F[col[i]].size()-1) {//???
                    int v=F[col[i]][j];
                    if(dis2[v]==0) continue;
                    ans=max(ans,dis1[col[i]]+dis2[v]-siz[col[1]]);
                }
            }
        }
        cout<<ans<<endl;
        return 0;
    }
    
  • 相关阅读:
    【转发】JS中如何判断null/ undefined/IsNull
    CSS3实现两行或三行文字,然后多出的部分省略号代替
    关于CodeFirst的使用教程
    把一个字符串里符合表情文字标签的地方全部替换为相应的图片的方法
    js 给json添加新的字段,或者添加一组数据,在JS数组指定位置删除、插入、替换元素
    用css3选择器给你要的第几个元素添加不同样式方法【转发】
    WebApi2 知识点总结
    把字符串每隔四个字符使用“-”中横线分隔的方法
    C语言strchr()函数:查找某字符在字符串中首次出现的位置
    linux 下安装开发组件包
  • 原文地址:https://www.cnblogs.com/sdfzhsz/p/9868659.html
Copyright © 2011-2022 走看看