• BZOJ 1922: [Sdoi2010]大陆争霸


    二次联通门 : BZOJ 1922: [Sdoi2010]大陆争霸

    /*
        BZOJ 1922: [Sdoi2010]大陆争霸
        
        最短路思路题
        带限制的转移
        _link[x] 记录的是当前城市有多少城市保护 
         
        记录两个距离
        一个是到当前点的最短路
        一个是最早能够进入当前点时间
        
        每次枚举当前点的必到点
        更新dis_2
        若都炸完后加入堆中 
         
        则答案就是 max (dis_1[N], dis_2[N]); 
         
    */
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <queue>
    
    #define Max 3050
     
    void read (int &now)
    {
        now = 0;
        register char word = getchar ();
        while (word < '0' || word > '9')
            word = getchar ();
        while (word >= '0' && word <= '9')
        {
            now = now * 10 + word - '0';
            word = getchar ();
        }
    }
    
    inline int max (int a, int b)
    {
        return a > b ? a : b;
    }
    
    struct Edge_Data
    {
        int to;
        int dis;
        int next;
    };
    
    struct Data_
    {
        int Id;
        int dis;
        
        Data_ (int __Id, int __dis) : Id (__Id), dis (__dis) {};
         
        bool operator < (const Data_ &now) const
        {
            return this->dis > now.dis; 
        }
        
        Data_ () {};
    };
    
    int N, M;
    int number[Max];
    
    int __link[Max][Max];
    int count[Max];
    
    int Answer;
    
    class Dijkstra_Type
    {
        private :
            
            Edge_Data edge[Max * 100];
            
            int Edge_Count ;
            int edge_list[Max];
            
            int dis_1[Max];
            int dis_2[Max];
            
            bool visit[Max];
            
        public :
            
            inline void Insert_Edge (int from, int to, int dis)
            {
                
                Edge_Count ++;
                edge[Edge_Count].to = to;
                edge[Edge_Count].next = edge_list[from];
                edge[Edge_Count].dis = dis;
                edge_list[from] = Edge_Count;
                
            }
        
            void Dijkstra (int Start, int End)
            {
                memset (dis_1, 0x3f, sizeof dis_1);
                
                std :: priority_queue <Data_> Queue;
                Queue.push (Data_ (Start, 0)); 
                dis_1[1] = 0;
                
                Data_ now;
                register int Maxn, res;
                register int pos;
                
                while (!Queue.empty ())
                {
                    now = Queue.top ();
                    Queue.pop ();
                    
                    if (visit[now.Id])
                        continue;
                    
                    visit[now.Id] = true;
                    Maxn = max (dis_1[now.Id], dis_2[now.Id]);
                    
                    for (int i = edge_list[now.Id]; i; i = edge[i].next)
                        if (dis_1[edge[i].to] > Maxn + edge[i].dis)
                        {
                            dis_1[edge[i].to] = Maxn + edge[i].dis;
                            int res = max (dis_1[edge[i].to], dis_2[edge[i].to]);
                            if (!number[edge[i].to])
                                Queue.push (Data_ (edge[i].to, res)); 
                        }
                        
                    for (int i = 1; i <= count[now.Id]; i ++)
                    {
                        pos = __link[now.Id][i];
                        number[pos] --;
                        dis_2[pos] = max (dis_2[pos], Maxn);
                        res = max (dis_1[pos], dis_2[pos]);
                        if (!number[pos])
                            Queue.push (Data_ (pos, res)); 
                    }
                }
                Answer = max (dis_1[End], dis_2[End]);
            }
    };
    
    Dijkstra_Type Make;
    
    int main (int argc, char *argv[])
    {
        
        read (N);
        read (M);
        int x, y, z;
        
        for (int i = 1; i <= M; i ++)
        {
            read (x);
            read (y);
            read (z);
            
            if (x != y)
                Make.Insert_Edge (x, y, z); 
        }
        
        for (int i = 1; i <= N; i ++)
        {
            read (number[i]);
            for (int pos = 1, x; pos <= number[i]; pos ++)
            {
                read (x);
                __link[x][++ count[x]] = i;
            }
        }
        
        Make.Dijkstra (1, N);
        
        printf ("%d", Answer);
        return 0;
    }
  • 相关阅读:
    JAVA下使用 连接sqlserver 驱动包
    Windows 7 、Windows Server 2008 和 Windows Server 2008 R2 的支持结束
    VBoxManage命令详解
    端口扫描之王——nmap入门精讲
    rehat-server7常见服务安装与配置总结
    mysql的安装和密码管理、mysql初始密码查找、密码修改、mysql登录
    vim常用命令总结 (转)
    关于《Python绝技:运用Python成为顶级黑客》的学习笔记
    常用MySQL图形化管理工具
    Chrome谷歌浏览器离线安装包下载
  • 原文地址:https://www.cnblogs.com/ZlycerQan/p/7076189.html
Copyright © 2020-2023  润新知